从矢量中删除元素,如果它们也在另一个矢量中

muq*_*waz 5 c++ vector erase

假设我有一个vector a = {"the", "of"}和一个vector b = {"oranges", "the", "of", "apples"}.

我想比较这两个向量和删除元素a也被加b.这就是我想出的:

for (int i = 0; i < a.size(); i++) {
    for (int j =0; j < b.size(); j++) {
       if (a[i] == b[j]) {
          a.erase(a.begin() + i);
       }
    }
}
Run Code Online (Sandbox Code Playgroud)

但是这个循环并没有删除最后一个元素a.奇怪的!

Cap*_*ous 8

问题是,当你删除a索引的第一个元素时,会从0增加到1.在循环的下一次迭代中,向量的大小1满足外循环的条件,导致它终止.你能避免,可能有必要解决这个问题,只需使用任何弄虚作假std::remove_if,std::find以及拉姆达.

#include <iostream>
#include <algorithm>
#include <vector>
#include <string>

int main()
{
    std::vector<std::string> a{ "the", "of" };
    std::vector<std::string> b{ "oranges", "the", "of", "apples" };

    auto pred = [&b](const std::string& key) ->bool
    {
        return std::find(b.begin(), b.end(), key) != b.end();
    };

    a.erase(std::remove_if(a.begin(), a.end(), pred), a.end());

    std::cout << a.size() << "\n";
}
Run Code Online (Sandbox Code Playgroud)

一个更好的测试将是转的内容ab.这将删除"the"和"of",留下"橘子"和"苹果".


Vla*_*cow 5

请尝试以下方法

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <cassert>

int main()
{
    std::vector<std::string> a = { "the", "of" };
    std::vector<std::string> b = { "oranges", "the", "of", "apples" };

    for ( auto it = a.begin(); it != a.end(); )
    {
        if ( std::find( b.begin(), b.end(), *it ) != b.end() )
        {
            it = a.erase( it ); 
        }
        else
        {
            ++it;
        }
    }

    assert( a.empty() );
}
Run Code Online (Sandbox Code Playgroud)

当然,如果要对矢量进行排序会更好.