【问题标题】:Erasing duplicates from two vectors using only iterators仅使用迭代器从两个向量中删除重复项
【发布时间】:2022-01-20 12:24:28
【问题描述】:

如何仅使用迭代器从两个字符串向量中删除重复项(从两个向量中删除它们)?

我想它不起作用,因为如果值已经被删除,它们就无法比较,但我想不出任何其他解决方案,只有当我有一个函数可以同时擦除两个元素时。

void obrisiIsteRijeci(std::vector<std::string>& v1, std::vector<std::string>& v2){
    for(auto it = v1.begin(); it != v1.end(); it++){
        auto it1 = it;
        for(auto it2 = v2.begin(); it2 != v2.end(); it2++){
            if((*(it2) == *(it1)) && (*(it1) == *(it2))){
                v1.erase(it1);
                v2.erase(it2);
            }
        }
    }
}

【问题讨论】:

  • 如果一个向量是[1 1 1],另一个是[2 2 2],那么两者都应该保持不变?
  • 向量是否已排序?如果是这样,那么您可以使用set_intersection 查找 then 向量之间的公共元素,然后您可以从每个向量中删除这些值。
  • v2.erase(it2) 在循环的下一次迭代中,it2++ 无效,因为您已将其删除。
  • 仅使用迭代器 -- 这到底是什么意思?光说这个基本上是没有意义的。因此,如果创建了另一个容器,并在那里使用了迭代器,这算不算?
  • 哇,if 条件中有这么多括号。我迷路了。

标签: c++ algorithm for-loop vector iterator


【解决方案1】:

我可以建议以下方法。在下面的演示程序中,为了简单起见,我使用了 std::vector&lt;int&gt; 类型的向量。

#include <iostream>
#include <vector>
#include <iterator>
$include <algorithm>

int main()
{
    std::vector<int> v1 = { 1, 2, 1, 2, 3, 4 }, v2 = { 1, 2, 3, 5 };

    for (auto first = std::begin( v1 ); first != std::end( v1 ); )
    {
        auto it = std::find( std::begin( v2 ), std::end( v2 ), *first );

        if (it != std::end( v2 ))
        {
            v2.erase( std::remove( it, std::end( v2 ), *first ), std::end( v2 ) );

            auto value = *first;
            auto offset = std::distance( std::begin( v1 ), first );

            v1.erase( std::remove( first, std::end( v1 ), value ), std::end( v1 ) );
            first = std::next( std::begin( v1 ), offset );
        }
        else
        {
            ++first;
        }
    }

    for (const auto &item : v1)
    {
        std::cout << item << ' ';
    }
    std::cout << '\n';

    for (const auto &item : v2)
    {
        std::cout << item << ' ';
    }
    std::cout << '\n';
}

程序输出是

4
5

【讨论】:

  • 这是从迭代器转换为索引并再次转换回迭代器。我认为问题中的“仅使用迭代器”限制是为了禁止使用索引。
  • @BenVoigt 您在哪里查看索引?使用迭代器的所有操作。
  • 变量offset是索引,std::distance将迭代器转换为索引,std::next将索引转换为迭代器
  • @BenVoigt 以同样的成功,您可以说像 ++it 这样的表达式(顺便说一下,它在函数 next 用于非随机访问迭代器的方式)转换了索引中的迭代器。:) 此外这样的调用 std::next(it) 等价于调用 std::next(it, 1);
  • 与索引相关的不是std::next 中的增量,而是步数参数。特别是当这个答案确实如此时,该数字是从std::begin(v1) 测量的。
猜你喜欢
  • 2021-11-08
  • 2019-10-05
  • 2019-02-11
  • 2020-08-03
  • 2016-06-29
  • 2013-10-05
相关资源
最近更新 更多