【问题标题】:c++ List Elements Randomly Not Deleted By Loopc ++列表元素随机不被循环删除
【发布时间】:2014-09-10 21:56:57
【问题描述】:

我有一个函数,当元素数量超过 250 时,它会从名为 bunnies 的映射(该映射包含类对象)和一个称为名称的列表(该列表包含映射的键)中随机删除元素。但是,随机地图元素将被删除,但列表条目不会(我认为这是正在发生的事情,尽管地图元素的一部分显然仍然存在)。结果是,当我使用第二段代码遍历列表并显示与这些键关联的映射值时,我得到了像底部示例一样的大负值。

显然列表元素没有被删除,但为什么呢?

void cull(std::map<std::string, Bunny> &bunnies, std::list<std::string> &names,int n)
{
    int number = n, position = 0;
    for (number = n; number > 125; number--)
    {
        position = rand() % names.size();
        std::list<std::string>::iterator it = names.begin();
        std::advance(it, position);
        bunnies.erase(*it);
        names.erase(it);
        it = names.begin();
    }
    std::cout << "\n" << n - 125 << "rabbits culled";
}

我使用此代码打印出地图值。

for (std::list<std::string>::iterator it = names.begin(); it != names.end(); it++)
    {
        n++;
        std::cout << n << "\t" << " " << *it << "\t" << bunnies[*it].a() << "\t" << bunnies[*it].s() << "\t" << bunnies[*it].c() << "\t" << bunnies[*it].st() << "\n";

这是输出。顶部是它应该显示的内容,底部是程序失败时发生的情况。

165      Tom_n  14      1       0       1
166      Lin_c  -842150451      -842150451      -842150451      -842150451

【问题讨论】:

  • 一个问题:你为什么要这样做? bunnies[*it].~Bunny();
  • @PaulMcKenzie 抱歉,这不应该存在并且不会影响问题(无论有没有它都会发生)。
  • 永远不要直接调用析构函数!它应该被自动调用。应用程序不会崩溃真是个奇迹。
  • @jeffpkamp 为什么是幻数125
  • std::advance(it, number) 应改为 std::advance(it, position)

标签: c++ list map


【解决方案1】:

问题似乎是这样的:

 std::advance(it, number);

这应该是position,而不是number

另一个问题是map 存储唯一名称。如果有多个同名的兔子怎么办?例如,如果list 有 3 个兔子名字“John”,则映射将只能包含一个“John”,因为映射中的键必须是唯一的。

如果名称可以重复,则使用multimap,或者如果兔子必须具有唯一名称,则使用std::set 而不是std::list

也许总的来说,您可以只使用std::map&lt;std::string, Bunny&gt;,而忘记std::list。地图本身就包含您需要的所有信息。除非我缺少某些东西,否则我认为不需要 std::list 来做多余的工作。

【讨论】:

  • 我改变了这个,这不是问题。这只是意味着它会从列表中删除一个非随机元素,因为number 总是比列表的大小短。 Position 只是一个小于列表大小的随机数。
  • 我更新了我的答案。你需要决定兔子是否有唯一的名字。
  • 名字是 16 个“名字”,姓氏随机分配一个 ascii 字符,提供大约 4000 个可能的名字。由于我将我的列表保持在 250 名成员以下,因此两个相同成员的机会非常小。也就是说,我还有一个未显示的程序的单独部分,它确保新生成的名称不在列表中。
  • @jeffpkamp 那么为什么要使用std::list&lt;std::string&gt;?使用std::set&lt;std::string&gt;,您不会遇到任何这些问题,重复的可能性为 0%。
  • 您确定问题出在 cull 方法上吗?您是否尝试在调用之前打印出所有兔子?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-12-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-08
相关资源
最近更新 更多