Reputation: 349
In this code, I have to iterate through a map full of leprechauns and they must be processed in a strict order from i=0,1,2,... However whenever I run my code I keep getting an error that states it is not incrementable. I have checked other posts on this error, but all of the askers are recommended to start their map from the beginning and I cannot restart it from the beginning. I was wondering if any of you guys knew a work around to this. Also, I have to use a map based data structure so a binary search tree or map structures. I would greatly appreciate any tips, comments, hints, or help.
#include <iostream>
#include <chrono>
#include <random>
#include <map>
#include <vector>
using namespace std;
class RandomNumberGenerator {
public:
RandomNumberGenerator(int x) :generator(x) {};
// return a double between -1 and 1
double randomBetween1and2() {
return (2.0*generator()) / generator.max() - 1.0;
}
private:
minstd_rand0 generator;
};
int N;
// Use a constant random number seed so behavior is consistent from run to run.
int RANDOM_SEED;
int main()
{
cout << "Enter seed for random number generator: ";
cin >> RANDOM_SEED;
RandomNumberGenerator rng(RANDOM_SEED);
cout << "Enter number of leprechauns: ";
cin >> N;
long playtime;
cout << "Enter game play time (seconds): ";
cin >> playtime;
playtime = playtime * 1000; // convert to milliseconds
double score = 0;
int nTrapped = 0;
// CODE FOR INITIALIZING DATA STRUCTURES GOES HERE
multimap<int, int> DataStructure;
int gold = 1000000;
for (int i = 0; i < N; i++)
{
//Create N-locations based on the amount of leprechauns.
//Key: Location Value: What leprechaun is present.
double location = i * 1000;
DataStructure.insert(make_pair(location, i + 1));
}
//Iterator to traverse around leprechauns:
//Vector for Gold:
//Creates N ints with default value of gold(1mil)
vector<double>LeprechaunGold(N, gold);
int t = 0; // keep track of number of iterations
auto start_time0 = chrono::high_resolution_clock::now();
auto timeSinceStartMS = 0;
multimap<int, int>::iterator it = DataStructure.begin();
do {
// CODE FOR A SINGLE ITERATION GOES HERE
//Iteration - Traverse through the data structure:
int vectorIterator = 0;
//1 The leprechaun jumps to a new location.
//// You can use the random number generator like so:
double r = rng.randomBetween1and2();
double x = 0;
x = x + r*gold;
DataStructure.insert(make_pair(x, it->second));
//Delete old location.
DataStructure.erase(it);
//2 Determine if Key is inbetween pit.
if (x >= -1000 || x <= 1000)
{
multimap<int, int>::iterator toBeDeleted = DataStructure.find(x);
//If it IS between -1000 and 1000(It's in the PIT. "I fell in the pit. You fell in the pit. We all were in the pit.... THE PIT.")
//Delete this leprechaun AND put goldVector(of that leprechaun) to 0, and place gold into score.
DataStructure.erase(toBeDeleted);
score += LeprechaunGold[vectorIterator];
LeprechaunGold[vectorIterator] = 0;
}
//3 Determine if multiple keys(multiple leprechauns in one spot)
//Count X.
if (DataStructure.count(x) >= 1)
{
//If there are greater than one, two leprechauns are occupying the same spot(same key)
multimap<int, int>::iterator toBeDeleted = DataStructure.find(x);
/*range = DataStructure.equal_range(x);
for (it = range.first; it != range.second; ++it)
{
}*/
}
//4 Leprechaun steals half gold from neighbor(s)
//Move to next leprechaun in Goldvector:
vectorIterator++;
t++;
it++;
// code to measure run time
auto end_time = std::chrono::high_resolution_clock::now();
auto timeSinceStart = end_time - start_time0;
timeSinceStartMS = chrono::duration_cast<chrono::milliseconds>(timeSinceStart).count();
} while (timeSinceStartMS < playtime);
cout << "Number of iterations = " << t << endl;
cout << "Number of trapped leprechauns = " << nTrapped << endl;
cout << "Score = " << (long)score << endl;
return 0;
}
Upvotes: 0
Views: 193
Reputation: 2759
You shouldn't modify the map inside your loop and make the iterator invalid. I believe this line is the source of your problem:
DataStructure.erase(it);
Put all of these inside a container like a vector, and then remove them after the loop ends. Or maybe reassign the iterator to the next iterator which is returned by erase, if you are using C++11.
it=DataStructure.erase(it);
Upvotes: 1