【问题标题】:Why this multiset print code results forever loop?为什么这个多集打印代码会导致永远循环?
【发布时间】:2012-11-18 18:21:09
【问题描述】:

我想打印出多重集中的每个重复项,但不知何故迭代器对我来说表现得很奇怪。如何修复此代码?这段代码导致了一个永远循环,这让我很吃惊。

#include <set>
#include <iostream>
#include <sstream>

static void print_duplicate(const std::multiset<int>& mset)
{
  std::stringstream error_msg;
  for (auto it = mset.begin(); it != mset.end(); ++it)
    {
      unsigned count = mset.count(*it);
      if (count < 2)
        continue;

      error_msg << "Duplicated numbers found:\n";

      for (unsigned i = 0; i < count; ++it, ++i)
        error_msg << "\tNum:" << *it << "\n";
    }

  std::cout << error_msg.str();
}

int main()
{
  std::multiset<int> mset;

  // fill it
  mset.insert(1);
  mset.insert(1);
  mset.insert(1);

  print_duplicate(mset);
}

编辑 我在循环结束时添加了一个--it

  for (unsigned i = 0; i < count; ++it, ++i)
    error_msg << "\tNum:" << *it << "\n";
  --it; // this line fix it
}

【问题讨论】:

    标签: c++ algorithm multiset


    【解决方案1】:

    for (unsigned i = 0; i &lt; count; ++it, ++i) 当这个循环结束时,it 将等于 mset.end() 并且由于你仍然有来自主循环的另一个 ++it,你得到的东西与 mset.end() 不同,因此程序永远不会结束.

    【讨论】:

      【解决方案2】:

      在您的外部循环中,您可能会多次增加it。因此,条件it != mset.end() 可能永远不会为真,因为结尾已经被跳过。增加一个过去的迭代器是未定义的行为,这意味着它也可能静默失败。

      一个可能的解决方案可能是在内部for-loop 中检查it != mset.end()

      for (unsigned i = 0; (i < count) && (it != mset.end()); ++it, ++i)
          error_msg << "\tNum:" << *it << "\n";
      

      【讨论】:

      • 这对我来说是一个永远的循环
      • 是的,只要在这个循环结束后输入--it
      【解决方案3】:

      问题似乎是您在没有发现的情况下滑过了终点。在您创建的mset 中,只有1s。这意味着count 将是 3,嵌套的fori 之上的一个)将执行 3 次;当它完成时,it 将等于 mset.end()。然后控制到达外部for 的末尾,it 递增,变为非法,更重要的是,与mset.end() 不同。这意味着外循环永远不会终止。

      【讨论】:

        【解决方案4】:

        快速修复:在内循环后添加一行:it--;

        Angew 的回答中解释了原因。

        【讨论】:

          【解决方案5】:

          将 for 循环更改为:

          for(std::container::iterator it=mset.begin(), it_next=it; it!=mset.end(); it=it_next) {
            ++it_next;
            ...
          }
          

          本质上,您正在跳过循环末尾,因为您正在根据迭代器检查变量。仅递增辅助迭代器将防止这种情况发生。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-09-11
            • 1970-01-01
            • 2021-03-20
            • 1970-01-01
            相关资源
            最近更新 更多