【问题标题】:Replacing items in a list using a C++ std::list iterator使用 C++ std::list 迭代器替换列表中的项目
【发布时间】:2013-06-18 06:54:14
【问题描述】:

我的代码的基本结构是:

using namespace std;
void recursiveFunction(list <int> &jobs,...){
list<int>::iterator i;
int ii;
//code missing
    for(i=jobs.begin(); i != jobs.end(); ++i){
        //more code missing
        list<int>::iterator tempi(i);
        ii=*i;
        jobs.erase(tempi);
        recursiveFunction(jobs,...);
        jobs.insert(i,ii);
    }
}

正如我所发现的,任何指向已擦除位置的指针都会失效,因此 i 也会失效。有没有办法以这种方式重新插入工作编号?没有每次递归创建一个新列表的性能损失?

除了列表迭代器之外,还有其他方法可以使用吗?

【问题讨论】:

  • 你到底想做什么?在我看来,您试图删除一个元素,然后将其插入到它曾经所在的位置
  • 当使用erase()进行迭代时,您必须使用函数的返回值进行进一步的迭代。
  • 在递归调用中所有这些擦除之后,迭代器 i 已衰减,那么为什么不使用 push_back 而不是 insert?
  • 同一个列表在多个递归级别被读取,如果没有更高级别两次读取相同的作业,我认为我不能使用 push_back...

标签: c++ list insert iterator erase


【解决方案1】:

list::erase 将迭代器返回到(最后一个)已擦除元素之后的元素,并且由于 list::insert 将在您传递它的迭代器的元素之前插入,这非常适合您的需求:

using namespace std;
void recursiveFunction(list <int> &jobs,...){
  //...
  for(auto i = begin(jobs); i != end(jobs);){ 
    //...
    auto tmpElem = *i;
    i = jobs.erase(i);
    recursiveFunction(jobs,...);
    jobs.insert(i,tmpElem);
  }
}

注意事项:

  • 使用i=jobs.erase(i) 可以有效地增加i。所以将增量留在 for 循环中。或者稍后使用i=jobs.insert(i,tmpElem),所以i 再次指向同一个元素
  • 出于良好的风格和可维护性考虑,尽可能将变量(例如 itmpElem)声明为本地变量
  • 给变量起有意义的名字

根据功能的作用,可能还有其他可能性来实现您想要的。这样,您将处理列表元素的每个子集,并且多次处理其中的许多子集。考虑列表中的内容{1,2,3},这是将要发生的事情(在伪代码中):

recursiveFunction({1,2,3},...)
  for-loop, i = &1
    erase(1)
    recursiveFunction({2,3},...)
      for-loop, i = &2
        erase(2)
        recursiveFunction({3},...)    //a
        insert(2)
      //...
    insert(1)
  for-looop, i = &2
    erase(2)
    recursiveFunction({1,3},...)
      for-loop, i = &1
        erase(1)
        recursiveFunction({3},...)    //b
        insert(1)
      //...
    insert(2)
  //...

a 行和 b 行看起来一样,尽管附加参数可能不一样 - 我无法从您的代码中分辨出来。因此,请牢记这一点,并考虑这是否是您真正想要的。

【讨论】:

  • 非常感谢!我应该说我正在使用它来枚举作业序列,如果作业序列不受欢迎,则提前退出。
【解决方案2】:

递归似乎不是解决您问题的正确工具。如果您有一个包含 { 1, 2, 3, 4 } 并且所有三个都符合条件的列表,看起来会发生这种情况:

递归({1,2,3,4}); it.1 = (1) 删除 1 递归({2,3,4}); it.2 = (2) 删除 2 递归({3,4}); it.3 = (3) 删除 3 递归({4}); it.4 = (4) 删除 4 递归({}) 重新插入 4 ({4}) 重新插入 3 ({3,4}) it.3 = (4) 删除 4 递归({3}); it.4 = (3) 删除 3 递归({}) 重新插入 3 ({3}) 重新插入 4 ({3,4}) 重新插入 2 ({2,3,4}) it.2 = (3) 删除 3 离开 ({2,4}) ... ETC ...

【讨论】:

    猜你喜欢
    • 2017-10-29
    • 2011-10-13
    • 1970-01-01
    • 1970-01-01
    • 2023-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多