Possible Logic Error: remove(vector.begin(), vector.end(), val)

huangapple go评论67阅读模式
英文:

Possible Logic Error: remove(vector.begin(),vector.end(),val)

问题

我正在寻找一种删除文件中某些行的方法。我在Stack Overflow上看到,最好的方法是将它写入一个向量,然后从数组中删除元素,然后将数组重新写入文件。我正在尝试这样做,并尝试使用remove方法来删除数组的元素。

我在这里找到了这个方法:

Removing Method

但这似乎不起作用,经过自己编译他们的代码后,我发现他们的代码也不起作用。

我是否漏掉了什么简单的东西?或者这是不正确的。这是他们的代码:

#include<bits/stdc++.h>
using namespace std;

int main(){
    vector<int> v;
    //Insert values 1 to 10
    v.push_back(20);
    v.push_back(10);
    v.push_back(30);
    v.push_back(20);
    v.push_back(40);
    v.push_back(20);
    v.push_back(10);

    vector<int>::iterator new_end;
    new_end = remove(v.begin(), v.end(), 20);

    for(int i=0; i<v.size(); i++){
        cout << v[i] << " ";
    }
    //Prints [10 30 40 10]
    return 0;
}

(进一步澄清,“不起作用”意味着:它打印出了20 10 30 20 40 20 10

英文:

I am looking for a way to delete certain lines in a file. I read on Stack Overflow that the best way to do this is to write it into a vector, and then remove the element from the array, and then read the array back into the file. I was doing this, and was attempting to remove the elements of the array by using the remove method.

I found this method here:

Removing Method

But this didn't seem to work, and after compiling their code for myself, I found the theirs didn't work either.

Is there something simple I'm missing? Or is this incorrect. This is their code:

#include&lt;bits/stdc++.h&gt;
using namespace std;

int main(){
    vector&lt;int&gt; v;
    //Insert values 1 to 10
    v.push_back(20);
    v.push_back(10);
    v.push_back(30);
    v.push_back(20);
    v.push_back(40);
    v.push_back(20);
    v.push_back(10);

    vector&lt;int&gt;::iterator new_end;
    new_end = remove(v.begin(), v.end(), 20);

    for(int i=0;i&lt;v.size(); i++){
        cout &lt;&lt; v[i] &lt;&lt; &quot; &quot;;
    }
    //Prints [10 30 40 10]
    return 0;
}

(For further clarification, 'didn't work' means: it printed 20 10 30 20 40 20 10)

答案1

得分: 3

只需像这样更改for循环:

new_end = remove(v.begin(), v.end(), 20);

for (auto first = v.begin(); first != new_end; first++) {
    cout << *first << " ";
}

或者你可以擦除已移除的元素:

v.erase(new_end, v.end());
for (int i = 0; i < v.size(); i++) {
    cout << v[i] << " ";
}

或者

v.erase(new_end, v.end());
for (const auto &item : v) {
    cout << item << " ";
}

或者你可以将标准算法std::remove的调用与成员函数erase相结合,像这样:

v.erase(remove(v.begin(), v.end(), 20), v.end());

请注意,如果你的编译器支持C++ 20,那么你可以直接写:

std::erase(v, 20);
英文:

Just change the for loop like

new_end = remove(v.begin(), v.end(), 20);

for ( auto first = v.begin(); first != new_end; first++){
    cout &lt;&lt; *first &lt;&lt; &quot; &quot;;
}

Or you could erase the removed elements like

v.erase( new_end, v.end() );
for(int i=0;i&lt;v.size(); i++){
   cout &lt;&lt; v[i] &lt;&lt; &quot; &quot;;
}

or

v.erase( new_end, v.end() );
for ( const auto &amp;item : v ){
   cout &lt;&lt; item &lt;&lt; &quot; &quot;;
}

Or you could combine the call of the standard algorithm std::remove with the member function erase like

v.erase( remove(v.begin(), v.end(), 20), v.end() );

Pay attention to that if your compiler supports C++ 20 then you can just write

std::erase( v, 20 );

答案2

得分: 2

std::remove() 实际上并未从指定范围中移除匹配的元素。它只是将它们移到范围的末尾,然后返回指向第一个被“移除”的元素的迭代器。你忽略了那个迭代器

要从std::vector中实际删除匹配的元素,之后需要调用它的 erase() 方法,例如:

auto new_end = remove(v.begin(), v.end(), 20);
v.erase(new_end, v.end());

否则,只需在循环中使用迭代器,在达到“被移除”的元素时停止迭代,例如:

auto new_end = remove(v.begin(), v.end(), 20);
for (auto iter = v.begin(); iter != new_end; ++iter) {
    cout << *iter << " ";
}
英文:

std::remove() doesn't actually remove matching elements from the specified range. It just moves them to the end of the range, and then returns an iterator to the first element that was "removed". You are ignoring that iterator.

To physically remove the matching elements from the std::vector, you need to call its erase() method afterwards, eg:

auto new_end = remove(v.begin(), v.end(), 20);
v.erase(new_end, v.end());

Otherwise, just use the iterator in your loop to stop iterating when you reach the "removed" elements, eg:

auto new_end = remove(v.begin(), v.end(), 20);
for(auto iter = v.begin(); iter != new_end; ++iter){
    cout &lt;&lt; *iter &lt;&lt; &quot; &quot;;
}

huangapple
  • 本文由 发表于 2023年2月27日 03:09:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/75574388.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定