简体   繁体   English

为什么在C ++中迭代遍历映射会失败?

[英]Why does iterating through a map fail in C++?

Consider the following snippet of code: 请考虑以下代码段:

map<wstring,int>::iterator it;
map<wstring,int> bimap;

//Creating Bigrams out of monograms
for (it= container.begin(); it != container.end();)
{
    bimap[it->first + L" "+((++it)->first)]++;
    ++it;
    ++it;
}

If I run this code the program crashes and the reason for that crash is the second increment of iterator it . 如果我运行此代码的程序崩溃和该崩溃的原因是迭代器的第二个增量it Why is it like this? 为什么会这样? The iterator needs to increment and I am incrementing it twice instead of once! 迭代器需要递增,我将它递增两次而不是一次! What's wrong with it? 它出什么问题了?

If I want to save two adjacent map item values into some other maps like I am actually doing in the above for statement, how should I go about it? 如果我想将两个相邻的地图项值保存到其他地图中,就像我在上面的声明中实际做的那样,我应该怎么做呢? What if I want to combine and store every 3 other items together? 如果我想将每3个其他项目组合在一起怎么办?

I need to update the iterator to go on respectively, but I have no idea how to do it. 我需要更新迭代器分别继续,但我不知道该怎么做。

You set your loop to end when you reach the container.end , but because you increment the iterator twice you reach the end, then with that second it++ you try to go further (error). 当你到达container.end ,你将你的循环设置为结束,但是因为你将迭代器增加两次直到结束,然后用那一秒你++尝试进一步(错误)。

Example: let's say you have 3 elements. 示例:假设您有3个元素。

it = container.begin()

++it // ok
++it //ok

it != container.end() //true

++it // ok BUT AT THIS MOMENT it = container.end !
++it // CRASH

you are incrementing your iterator several times 你正在多次递增你的迭代器

for (it= container.begin(); it != container.end();)
{
    bimap[it->first + L" "+((++it)->first)]++;  //increment!
    ++it;  //increment!
    ++it;  //increment!
}

so you night be at the last element, enter the loop because it != container.end() condition is met and then go out of bounds. 所以你晚上在最后一个元素,进入循环,因为it != container.end()条件满足,然后超出界限。

if you know you will do 2 increments always, but end if there is only one element left, then you might consider this: 如果你知道你总是会做2个增量,但如果只剩下一个元素就结束,那么你可能会考虑这个:

for (it= container.begin(); it != container.end();)
{
    //do something
    ++it;  //increment!

    if(it!=container.end()){  //check again. can we move forward?
    //do something
    ++it;  //increment!
    }
}

just increment once on each iteration, and use an auxiliary counter modulo 3 (reset it after each 3 iterations) and do the task you want to do every time it is 0. something like: 只需在每次迭代时递增一次,并使用辅助计数器模3(在每3次迭代后重置它)并执行每次它想要执行的任务,例如:

int counter_mod3;
for (it= container.begin(); it != container.end();)
{
  if(counter_mod3 == 0) // This zero chooses the phase on which the "sampling" is to be made
    bimap[it->first + L" "+(it->first)]++;  //increment!

  ++it;  //increment!
  counter_mod3 = (counter_mod3++) % 3;
}

If you want to start on other element, instead of the first, just change the phase to 1 or 2 如果要从其他元素开始,而不是第一个元素,只需将阶段更改为1或2即可

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM