【问题标题】:Erase a vector element from list of vectors c++从向量c ++列表中删除向量元素
【发布时间】:2018-01-19 20:43:51
【问题描述】:

我一直在从这个论坛和其他人那里寻找解决这个问题的方法。我发现的唯一结果是关于迭代列表或访问向量列表中的元素。所以我想访问一个向量的擦除()函数。但是我需要在向量包含在列表容器中的情况下完成它。我有一个示例代码可以帮助解释。

#include<vector>
#include<list>
#include<iostream>

using namespace std;

int main()
{
    vector <int> a1 = { 1, 1, 1, 1, 1 };
    vector <int> a2 = { 2, 2, 2, 2, 2 };
    vector <int> a3 = { 3, 3, 3, 3, 3 };

    list<vector<int>> listVec;

    listVec.push_back(a1);
    listVec.push_back(a2);
    listVec.push_back(a3);

    for (auto p : listVec){

        for (auto p1 : p){
            cout << p1;
        }
        cout << "\n";
    }


}

那么从向量 a2 中删除一个元素的最简单方法是什么,因为它包含在列表中。现在我什至没有错误的版本。 这段代码应该在遍历循环的某个地方,但我写不出来。

谢谢

【问题讨论】:

标签: c++ c++11


【解决方案1】:

好的,标准的做法:

auto iter = listVec.begin();
std::advance(iter, 1); // get second element
iter->erase(iter->begin() + n); // erase nth element of second element of list

在你的 for 循环中——你需要迭代对元素的引用——而不是元素的副本,否则你只能从向量的副本中删除元素:

int pos = 0;
for (auto& p : listVec){
//       ^
   if (++pos == 1)
   {
       p.erase(p.begin() + n); // erase nth element of second element of list
   }
}

参考文献列表:


奖励答案:

对于您在 cmets 中提到的问题 - 您在哪里有容器 Document 和迭代器到 Document - 比如 Text_iterator - 最好是遵循 stl 方案 - 所以将 erase 函数添加到您的 Document 并制作这个Text_iterator的同学,见:

class Text_iterator {   // keep track of line and character position within            a line
    list<Line>::iterator ln;
    Line::iterator pos;
    friend class Document; 

还有:

struct Document {
    list<Line> line;            //doucument is a list of lines
    void erase(Text_iterator iter)
    {
        iter.ln->erase(iter.pos);
    }

【讨论】:

  • 有没有办法在没有提前()的情况下做到这一点。完美的情况是我可以输入适当元素的迭代器并将其删除。有没有这样的选择。
  • @fredric list iterator 不是随机访问迭代器,所以不是,这是不可能的 - 请参阅 en.cppreference.com/w/cpp/concept/BidirectionalIterator ,但是您可以拥有向量的向量,而不是向量列表...
  • @fredric 好吧,有一个uniform container erasure 的提案。很快,您就可以使用任何类型的容器std::erase(listVec, "bad word")std::erase_if(listVec, [](auto x) -&gt; { return f(x); })!非常简洁,但我们要等到 C++17 才能看到:(
  • 您发布的代码有效并回答了一个问题。但我问的原因是因为我想在早期的程序上工作,我遇到了麻烦,但我仍然无法修复。较早的帖子stackoverflow.com/questions/33572031/… 指出了文本处理程序的问题。我找不到使用遍历字符向量列表的自定义迭代器从该类文档中删除单词的方法。我试图制作一个先删除一个字符但卡住的函数
  • 感谢您对Text_iterator问题的回复。我试图在结构中定义函数并得到以下编译错误:错误2错误C2232:'->Text_iterator :: ln':左操作数具有'类'类型,使用'。'错误 4 错误 C2232: '->Text_iterator::pos' : 左操作数具有 'class' 类型,使用 '.' ?错误 1 ​​错误 C2819:类型 'Text_iterator' 没有重载成员 'operator ->' 是否需要重载访问运算符。试图得到一些例子,它似乎非常具体。还有其他方法吗
【解决方案2】:

迭代

for (auto p : listVec){

在迭代时为列表中的每个向量制作一个副本。因此,虽然您可以调用 p.erase 来擦除该向量的一个元素,但这只会影响副本 p 而不会影响列表中的向量。

如果你这样做

for (auto &p : listVec){

p 现在将成为列表中每个向量的引用。所以现在如果你调用p.erase,那会影响列表中的向量。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多