Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++:在重复列表时删除列表的多个元素_C++_List_Iterator_Erase - Fatal编程技术网

C++:在重复列表时删除列表的多个元素

C++:在重复列表时删除列表的多个元素,c++,list,iterator,erase,C++,List,Iterator,Erase,我知道如何擦除列表中的元素,并且该擦除返回一个有效的迭代器。我的问题是,我不仅要删除一个元素,还要删除多个元素 实际上我的代码是 for(list<Treenode*>::iterator it=currentLevel->begin(); it!=currentLevel->end(); ++it){ if(something(*it)) { for(list<Treenode*>::iterator it2=currentN

我知道如何擦除列表中的元素,并且该擦除返回一个有效的迭代器。我的问题是,我不仅要删除一个元素,还要删除多个元素

实际上我的代码是

 for(list<Treenode*>::iterator it=currentLevel->begin(); it!=currentLevel->end(); ++it){
     if(something(*it))  {
         for(list<Treenode*>::iterator it2=currentNewLevel->begin();it2!=currentNewLevel->end();){
             if (somethingDifferent(*it2)) {
                 it2=currentLevel->erase(it2);
             } else {
                 ++it2;
             }
         }
     }
 }
当然,这是行不通的,因为它没有改变。我不知道如何更改迭代器,但请继续执行此迭代步骤


谢谢你的阅读。我希望有人知道答案。

通常,根据条件从列表中删除元素的方法是使用member函数

bool pred(const Treenode* t) { .... }
currentNewLevel.remove_if(pred);
谓词可以是函子,因此它可以保留实现删除条件所需的任何状态:

#include <algorithm> // for std::find_if
#include <list>

// unary predicate functor. Returns true if an element of a reference
// list satisfies "something" and the functor call argument satisfies "somethingDifferent"
struct Pred
{
  Pred(const std::list<Treenode*>& nodes) : nodes_(nodes) {}
  bool (const Treenode* t) const
  {
    return std::find_if(nodes_.begin(), nodes_.end(), something) != nodes_.end() &&
           somethingDifferent(t);
  }
 private:
  const std::list<Treenode*>& nodes_;
};

通常,根据条件从列表中删除元素的方法是使用成员函数

bool pred(const Treenode* t) { .... }
currentNewLevel.remove_if(pred);
谓词可以是函子,因此它可以保留实现删除条件所需的任何状态:

#include <algorithm> // for std::find_if
#include <list>

// unary predicate functor. Returns true if an element of a reference
// list satisfies "something" and the functor call argument satisfies "somethingDifferent"
struct Pred
{
  Pred(const std::list<Treenode*>& nodes) : nodes_(nodes) {}
  bool (const Treenode* t) const
  {
    return std::find_if(nodes_.begin(), nodes_.end(), something) != nodes_.end() &&
           somethingDifferent(t);
  }
 private:
  const std::list<Treenode*>& nodes_;
};

边做边循环。它大部分也是++的,所以性能应该很好

std::vector<PdfTextRegion*>::const_iterator textRegion = m_pdfTextRegions.begin();
    while(textRegion != m_pdfTextRegions.end())        
    {
        if ((*textRegion)->glyphs.empty())
        {
            m_pdfTextRegions.erase(textRegion);
            textRegion = m_pdfTextRegions.begin();
        }
        else
            textRegion++;
    }

边做边循环。它大部分也是++的,所以性能应该很好

std::vector<PdfTextRegion*>::const_iterator textRegion = m_pdfTextRegions.begin();
    while(textRegion != m_pdfTextRegions.end())        
    {
        if ((*textRegion)->glyphs.empty())
        {
            m_pdfTextRegions.erase(textRegion);
            textRegion = m_pdfTextRegions.begin();
        }
        else
            textRegion++;
    }

非常感谢。问题是我在外循环中做了一些其他的事情。我可以用你的方法处理内部循环,但外部循环的迭代器无效。@user2693497你可以编写一个使用currentLevel的函子。我并不认为外循环迭代器有什么问题。您可能应该解释一下您试图实现的目标。@Name我添加了一个带有函子的示例。它做了我认为你的原始代码试图做的。再次感谢你。ifSomethinDifferent{…}部分只是我为每个列表条目所做工作的一小部分。我做了很多事情,最终改变了其他列表条目。迭代器不应访问已更改的列表条目。所以我想从currentLevel中删除它们。所以我真的需要外环。我认为从我迭代的列表中删除元素会导致分段错误。但这只有在移除迭代器此时显示的元素时才是正确的。所以我只需要确保我没有删除这个元素。谢谢你的帮助!非常感谢。问题是我在外循环中做了一些其他的事情。我可以用你的方法处理内部循环,但外部循环的迭代器无效。@user2693497你可以编写一个使用currentLevel的函子。我并不认为外循环迭代器有什么问题。您可能应该解释一下您试图实现的目标。@Name我添加了一个带有函子的示例。它做了我认为你的原始代码试图做的。再次感谢你。ifSomethinDifferent{…}部分只是我为每个列表条目所做工作的一小部分。我做了很多事情,最终改变了其他列表条目。迭代器不应访问已更改的列表条目。所以我想从currentLevel中删除它们。所以我真的需要外环。我认为从我迭代的列表中删除元素会导致分段错误。但这只有在移除迭代器此时显示的元素时才是正确的。所以我只需要确保我没有删除这个元素。谢谢你的帮助!也许我头脑简单:ifit2==在擦除之后也调整它也许我头脑简单:ifit2==在擦除之后也调整它性能可能很糟糕-最坏的情况发生在**2,因为它每次都从一开始就开始。remove_if版本将目标元素交换到末尾,保证了线性时间和单次传递。它在各个方面都绝对更好。性能可能很糟糕-最糟糕的情况是在**2上,因为它每次都从一开始就开始。remove_if版本将目标元素交换到末尾,保证了线性时间和单次传递。它在各方面都绝对更好。