【问题标题】:How to conditionally remove an element from a list using an iterator?如何使用迭代器有条件地从列表中删除元素?
【发布时间】:2015-08-21 07:53:22
【问题描述】:

问题:

我正在编写一个简单的文件管理器应用程序。在这个程序中,我有一个“目录”类:

class Directory
{
public:
    Directory(string address, string directoryname)
    {
        this->path = address;
        this->name = directoryname;
    }
    string GetFullPath(){ return path == "/" ? path + name : path + "/" + name; }
    string path;
    string name;
    string user;
};

以及目录对象的链表:

list<Directory*> DirectoryList;

我想在 linux 中实现"rm -r directorypath" shell 命令,所以我需要浏览列表并删除“directorypath”目录及其所有子目录。问题是我不知道如何浏览链接列表并删除其父目录为“directorypath”的所有目录。这两种方法我都试过了:

方法一:

此方法遇到运行时错误,因为它在第一次删除后无法再访问列表。

for (auto address : DirectoryList)
        if (address->GetFullPath() == directorypath)
        {
            for (auto subdirectory : DirectoryList)
            if (subdirectory ->path == address->GetFullPath())
                DirectoryList.remove(subdirectory );
        }

方法2:

for (auto address : DirectoryList)
        if (address->GetFullPath() == directorypath)
        {
            for (auto it = DirectoryList.begin(); it != DirectoryList.end();)
                it = DirectoryList.erase(it);
            return true;
        }

此方法即使在删除后也可以完美访问所有元素,但我不知道如何使用迭代器 it 来检查这个 if 条件:

if (subdirectory ->path == address->GetFullPath())

【问题讨论】:

  • 你可以用*it访问迭代器指向的对象,也就是说,它的行为很像一个指针。
  • 阅读Erase-Remove Idiom 以获得安全和干净的方法。

标签: c++ linked-list listiterator


【解决方案1】:

您的 方法 1 失败,因为std::list.remove(val) 删除了列表中所有比较等于 val 的元素。你调用它一次,你就完成了。 for() 循环不应该存在,这不是它的预期使用方式。很好的例子是here

请注意,此方法将修改您的容器及其大小。您需要在这里小心并确保您的迭代器在调用erase 后仍然有效。我的直觉是,迭代器确实无效,这就是你得到错误的原因。

您的方法 2 看起来几乎没问题。首先,请放松 niceguy 的建议来检查情况:

if ((*it).path == address->GetFullPath())

现在,请记住,删除 it 将更新迭代器以指向您删除的迭代器之后的位置。这算作对迭代器it 的一次更新。它将在for 循环中进一步更新,但这不是您想要的(即每次迭代两次更新意味着您正在跳过一些元素)。你可以试试这样的:

auto it = DirectoryList.begin()
while (it != DirectoryList.end())
{
   if ((*it).path == address->GetFullPath())
       DirectoryList.erase(it);
}

【讨论】:

  • @KamranKia 这回答了你的问题吗?
猜你喜欢
  • 2013-11-25
  • 1970-01-01
  • 2017-12-15
  • 2014-05-06
  • 2016-07-19
  • 1970-01-01
  • 2012-02-12
  • 1970-01-01
  • 2010-12-07
相关资源
最近更新 更多