使用 C++ std::list 迭代器替换列表中的项目

Dyl*_*ebb 3 c++ iterator list insert erase

我的代码的基本结构是:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

正如我所发现的,任何指向被擦除位置的指针都是无效的,所以 i 是无效的。有没有办法以这种方式重新插入工作编号?如果没有每次递归创建新列表的性能影响?

也许有没有办法使用列表迭代器以外的其他东西?

Arn*_*rtz 5

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);
  }
}
Run Code Online (Sandbox Code Playgroud)

笔记:

  • 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)
  //...
Run Code Online (Sandbox Code Playgroud)

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