Skip to content

Instantly share code, notes, and snippets.

@sturgle
Created October 13, 2014 04:05
Show Gist options
  • Save sturgle/c76c8ea62f540fbce46d to your computer and use it in GitHub Desktop.
Save sturgle/c76c8ea62f540fbce46d to your computer and use it in GitHub Desktop.
enhanced map with random
#include <vector>
#include <map>
#include <utility>
#include <iostream>
using namespace std;
class ExMap {
map<int, int> _map; // key to index of _keyVals
vector<pair<int,int>> _keyVals;
public:
ExMap() {
srand(time(NULL));
}
void set(int key, int value);
bool hasKey(int key);
int get(int key);
void remove(int key);
int random();
};
void ExMap::set(int key, int value) {
if (!hasKey(key)) {
_keyVals.push_back(make_pair(key, value));
_map[key] = _keyVals.size() - 1;
} else {
_keyVals[_map[key]].second = value;
}
}
bool ExMap::hasKey(int key) {
return _map.find(key) != _map.end();
}
int ExMap::get(int key) {
return _keyVals[_map[key]].second;
}
void ExMap::remove(int key) {
if (hasKey(key)) {
int idx = _map[key];
int tail = _keyVals.size() - 1;
_keyVals[idx] = _keyVals[tail];
_map.erase(key);
_keyVals.pop_back();
}
}
int ExMap::random() {
int idx = rand() % _keyVals.size();
return _keyVals[idx].second;
}
int main() {
ExMap em;
cout << "============basic test ============" << endl;
em.set(1,2);
em.set(2,3);
cout << em.get(1) << endl;
cout << em.get(2) << endl;
em.set(2,4);
cout << em.get(2) << endl;
em.remove(2);
cout << em.hasKey(2) << endl;
cout << "============random test ============" << endl;
for (int i = 0; i < 10; i++) {
em.set(i, i*10 + i);
}
map<int, int> count;
for (int i = 0; i < 100000; i++) {
int r = em.random();
if (count.find(r) == count.end()) {
count[r] = 1;
} else {
count[r]++;
}
}
for (auto iter = count.begin(); iter != count.end(); iter++) {
cout << iter->first << ":" << iter->second << endl;
}
cout << "============random after remove test ============" << endl;
count.clear();
for (int i = 0; i < 100000; i++) {
int r = em.random();
if (count.find(r) == count.end()) {
count[r] = 1;
} else {
count[r]++;
}
}
em.remove(7);
em.remove(2);
for (int i = 0; i < 100000; i++) {
int r = em.random();
if (count.find(r) == count.end()) {
count[r] = 1;
} else {
count[r]++;
}
}
for (auto iter = count.begin(); iter != count.end(); iter++) {
cout << iter->first << ":" << iter->second << endl;
}
return 0;
}
/*
============basic test ============
2
3
4
0
============random test ============
0:9999
11:9871
22:9855
33:10173
44:10014
55:10055
66:10043
77:10029
88:9973
99:9988
============random after remove test ============
0:22527
11:22579
22:9982
33:22731
44:22485
55:22408
66:22653
77:9964
88:22287
99:22384
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment