我有一个代码:

it = tableAndHand.begin();
while(++it != tableAndHand.end()) {
 if(*it == *(--it)) {
  ++cardCount;
  ++it;
 } else {
  cardCounts1.insert(pair<int,int>(cardCount,*it));
  while(cardCount > 1) {
   it = tableAndHand.erase(--it);
   --cardCount;
  }
 ++it;
 }
}
cardCounts1.insert(pair<int,int>(cardCount,*(--it)));
while(cardCount > 1) {
 it = tableAndHand.erase(--it);
 --cardCount;
}

tableAndHand是一开始包含7个值的列表,在删除一些值后在那个有问题的地方出现了细分错误,为什么会这样呢?

list中的值已排序,并且在列表{0,0,0,1,1,1,1,2}上迭代1的地方失败(正确擦除2 0之后,列表的大小已经是5)。

我只想将唯一值的计数保存到映射cardCounts1中,并从列表中删除重复的值,我的算法有什么问题?

编辑:看起来问题是(* it == *(-))并未从左到右进行评估,尽管我在有关cplusplus.com以及一些运算符的文章中找不到“ ==”的评估他们说其他网站从左到右进行评估。 关于它的一些好的链接?

EDIT2:好的,它有效,我忘了给它分配tableAndHand.erase(-it)迭代器,现在它可以完美,快速地工作了:)

#1楼 票数:3

你增加it三倍的循环,对年底比较之前。

您删除而不保存新的迭代器。

很多副作用。

没有定义if(*it == *(--it)) {的顺序,因此您可能最终将一个元素if(*it == *(--it)) {自身进行比较。 ==不是序列点,因此*it*(--it)可以按任意顺序求值)。

您不检查tableAndHand是否为空-在检查之前增加it

#2楼 票数:1

您在循环的每次迭代中将it递增两次:

while(++it != tableAndHand.end()) {  // <---- IN THIS LINE
  //HERE IS THE PROBLEM
  if(*it == *(--it)) {
   ++cardCount;
   ++it;      // <----- AND EITHER HERE
  } else {
    cardCounts1.insert(pair<int,int>(cardCount,*it));
    while(cardCount > 1) {
     tableAndHand.erase(--it);
     --cardCount;
    }
    ++it;   // <----- OR HERE
  }
}

这意味着您应该先于列表末尾运行,然后在while循环中进行比较:

while (++it != tableAndHand.end())

因为迭代器永远不会精确指向容器的末尾,所以永远产生真。

如果元素数为偶数,则可以工作(尽管由于有时会删除元素,所以很难预测)。


另一个问题是,初始迭代将立即it一次递增,如果该容器恰好为空,则将其立即推到容器末端之外。

#3楼 票数:1

if(*it == *(--it))

这段代码的行为是不确定的:编译器可以在比较的右侧对--it进行求值, it在左侧对它进行求值,或者可以用相反的方式进行求值。

更一般地,对于列表,不要尝试使用相同的迭代器来访问两个相邻的元素。 它只会导致代码混乱。 使用两个迭代器:一个当前位置和一个拖车,并在每次循环时分别递增一次和仅递增一次。

  ask by Lukas Salich translate from so

未解决问题?本站智能推荐:

2回复

使用C ++ std :: list iterator替换列表中的项目

我的代码的基本结构是: 正如我所发现的,任何指向被擦除位置的指针都是无效的,因此我无效。 有没有办法以这种方式重新插入工作号码? 没有创建每个递归的新列表的性能? 有没有办法使用除列表迭代器之外的东西?
2回复

C ++ list :: erase没有匹配功能

我目前正在尝试遍历char类型的链接列表。 当遇到一个参数时(如果它包含字母“ w”),我尝试使用list :: erase删除列表项。 我只是希望收到有关使用此功能的建议,我只看到了带有类型为int链表的示例,而且我无法确定它是否为char或原因是什么,因此无法确定。 当我尝试编译以下代
2回复

C++:在迭代列表时删除列表的多个元素

我知道如何擦除列表的元素,并且擦除返回一个有效的迭代器。 我的问题是,我不仅要删除一个元素,还要删除多个元素。 实际上我的代码就像 当然这行不通,因为it没有改变。 我不知道如何更改迭代器,但继续这个迭代步骤。 感谢您的阅读。 我希望有人知道答案。
2回复

从std :: list中删除项目,只能访问迭代器

std :: list是一个双链表。 这是否意味着只能访问迭代器才能从列表中删除项目? 也许我的问题不够明确。
2回复

列表迭代器的C ++分段错误

我在访问指向地图内列表的迭代器时遇到麻烦。 尽管互联网上描述了许多类似的问题,但我没有找到正确的解释。 我有一个包含“可见对象”的管理器对象; 单身时,它们将存储在地图中;当它们相同时,它们将被存储在地图中的列表中。 我有一些必须浏览整个地图的函数,并且在尝试访问列表迭代器时程序崩溃
1回复

解除引用列表迭代器段错误

我正在为bison / flex中的语言组合一个解析器,并且已经实现了抽象语法树。 一旦我实现了一些非常原始的静态类型检查,我就开始在我的列表迭代器上得到分段错误,即迭代我的语句列表。 保存列表迭代器的根程序节点: stmtList是指向语句指针列表的指针。 它必须是一个指向列
2回复

取消引用已初始化为list.begin的迭代器时收到segfault

当取消引用已初始化为list.begin()的迭代器时,我遇到了段错误。 这是来自gdb的错误: bt已满的gdb输出显示迭代器为NULL。 尽管迭代器为NULL, it != (list_empty[i]).end()评估it != (list_empty[i]).en
1回复

在递归函数中使用迭代器会导致分段错误

我编写了一个程序,该程序接受N个代表学生技能水平的整数测试用例,并尝试寻找最小组的总数,如果唯一的限制是团队中没有平等的技能水平,并且技能差距不大于1。因此,以下测试用例: 将输出: 由于可能的团队是{-4,-3,-5}和{4,5,2,3},因为第一组只有三个成员,所以输出为3。