删除两个向量中的重复项

时间:2018-05-15 10:38:37

标签: c++ algorithm vector duplicates std-pair

  

我将尝试用以下示例解释我的问题:

vector<pair<string, string>> a = { { "A","1" }, {"B","2" },{ "C","3" },{ "D","3" },{ "E","5" } };

vector<pair<string, string>> b = { { "A","1" },{ "B","3" },{ "D","3" },{ "E","4" },{ "Z","5" } };

什么是最有效的方法来擦除重复并将输出转换为相同的向量?对的数量非常大,比如大约10万。

两个向量都按第一个元素排序。

vector<pair<string, string>> a = { { "B","2" },{ "C","3" },{ "E","5" } };

vector<pair<string, string>> b = { { "B","3" },{ "E","4" },{ "Z","5" } };

问题是,我需要在删除重复项后比较这些向量。 该对中的第一个元素是文件路径,第二个元素是它的校验和。 例如,如果我在第一个容器中有"B","2",而"B","3"是第二个容器,我可以将此文件列为“已修改”。我愿意使用std::set,如果这样可以使这个问题更容易。

3 个答案:

答案 0 :(得分:7)

使用运行索引将为您提供O(len(a)+ len(b))时间复杂度和O(1)额外空间(给定echo '{"123":"abc","231":"dbh","452":"xyz"}' | jq -r 'to_entries | .[] | "\"" + .key + "\",\"" + (.value | tostring)+ "\""' a已经排序)

b

答案 1 :(得分:1)

我不认为任何标准库算法在这里会有直接帮助。

我们首先检查是否应该删除(从两者),否则我们推进指向较小值的迭代器并继续。

for (auto ait = a.begin(), bit = b.begin(); ait != a.end() && bit != b.end();)
{
    if (*ait == *bit)
    {
        // Potenitally multiple duplicate values
        ait = a.erase(std::remove(ait, a.end(), *ait), a.end());
        bit = b.erase(std::remove(bit, b.end(), *bit), b.end());
    }
    else if (*ait < *bit) ++ait;
    else ++bit;
}

答案 2 :(得分:0)

您可以使用STL库中的一些算法来帮助解决此任务。首先找到相同的元素并将它们放在临时向量中,然后从每个向量中删除这些元素,参见代码示例:

vector<pair<string, string>> a = { { "A","1" }, {"B","2" },{ "C","3" },{ "D","3" },{ "E","5" } };
vector<pair<string, string>> b = { { "A","1" },{ "B","3" },{ "D","3" },{ "E","4" },{ "Z","5" } };

//Vector to hold same elements
vector<pair<string, string>> same_elements {};

//Fill same_elements vector
std::for_each(a.begin(), a.end(), [&same_elements, b]( pair<string, string>& el )
              {
                  if( find(b.begin(), b.end(), el) != b.end() )
                  {
                      same_elements.push_back(el);
                  }
              });

//Remove same elements from a and b
std::for_each(same_elements.begin(), same_elements.end(), [&a, &b]( pair<string, string>& el_to_delete )
              {
                  auto It_a = find(a.begin(), a.end(), el_to_delete);
                  if( It_a != a.end() )
                  {
                      a.erase(It_a);
                  }

                  auto It_b = find(b.begin(), b.end(), el_to_delete);
                  if( It_b != b.end() )
                  {
                      b.erase(It_b);
                  }
              });

我使用std::for_each迭代向量的每个元素std::find以在向量中找到所需的元素,并使用erase向量方法通过迭代器从向量中擦除相同的元素。

相关问题