代码之家  ›  专栏  ›  技术社区  ›  yesraaj

从两个向量中删除公共实体?

  •  5
  • yesraaj  · 技术社区  · 17 年前

    说我有 vector<class1a>,vector<class1b> 如何从两者中删除公共实体 我已经为Class1对象Class1a、Class1b定义了==运算符

    6 回复  |  直到 16 年前
        1
  •  8
  •   Luc Touraille    16 年前

    这个 stl algorithms 提供多个函数来执行集合操作,尤其是计算 set symmetric difference ,这就是你需要的。

    以下是使用示例:

    #include <algorithm>
    #include <vector>
    
    int main(int argc, char **argv) {
    
        std::vector<int> v1;
        v1.push_back(1);
        v1.push_back(2);
        v1.push_back(3);
        v1.push_back(4);
        v1.push_back(5);
        v1.push_back(6);
    
        std::vector<int> v2;
        v2.push_back(2);
        v2.push_back(4);
        v2.push_back(6);
        v2.push_back(8);
    
        // Ranges must be sorted!
        std::sort(v1.begin(), v1.end());
        std::sort(v2.begin(), v2.end());
    
        std::vector<int> res; // Will contain the symmetric difference
        std::set_symmetric_difference(v1.begin(), v1.end(), 
                                      v2.begin(), v2.end(), 
                                      std::back_inserter(res));
    
        // Copy result to the output
        std::copy(res.begin(), res.end(), std::ostream_iterator<int>(cout, " "));
        // Prints "1 3 5"
    
        return 0;
    }
    

    std::set_symmetric_difference 取两个范围(即两对输出器)和一个输入器,将结果放在其中。它还将迭代器返回到结果范围的末尾。


    编辑

    我刚刚读了你对你问题的评论。如果要修改两个原始向量,可以使用 std::set_difference :

    vector<int>::iterator endRange;
    endRange = set_difference(v1.begin(), v1.end(), 
                              v2.begin(), v2.end(), 
                              v1.begin());
    v1.erase(endRange, v1.end());
    

    这里,我们把设定差v1-v2的结果放入v1。但是,我们不能做相反的事情,因为v1现在被修改了。解决方案是计算v1和v2的交点,然后计算与此交点的差:

    vector<int> inter;
    set_intersection(v1.begin(), v1.end(),
                     v2.begin(), v2.end(),
                     back_inserter(inter));
    // inter is "2 4 6"
    
    v1.erase(set_difference(v1.begin(), v1.end(),
                            inter.begin(), inter.end(),
                            v1.begin())
             v1.end());
    // v1 is "1 3 5"
    
    v2.erase(set_difference(v2.begin(), v2.end(),
                            inter.begin(), inter.end(),
                            v2.begin())
             v2.end());
    // v2 is "8"
    

    我想有更多的性能解决方案,但这一个是明确的,并真正传达了您的意图,使用广为人知的STL算法。

        2
  •  1
  •   Dyin    17 年前

    在stl header算法中,是一个称为“set_symmetric_difference”的函数,它将把一个元素的所有元素都放在一个目标范围内,但不是将两个源范围都放在一个目标范围内。

    记住,两个范围都必须开始排序。

    msdn documentation

        3
  •  0
  •   slacy    17 年前

    对这两个向量进行排序,然后并行遍历它们,执行一个常见的合并操作。这将告诉你哪些项目是相同的。

        4
  •  0
  •   i_am_jorf    17 年前

    简单的方法是进行n^2迭代,将第一个向量中的每个元素与第二个数组中的每个元素进行比较,并将匹配项添加到第三个向量中。完成n^2迭代后,将遍历第三个向量并从前两个向量中删除这些对象。

    不是最好的解决方案,但取决于你期望向量有多大,它可能是最简单的解决方案之一。

        5
  •  0
  •   dirkgently    17 年前

    对于中的每对项目 class1a class1b ,如果它们不相等,则将它们添加到输出集。否则,只添加一个这样的实例。对数组的最小长度重复此操作。如果其中一个更长,您将得到更多——尝试将所有这些添加到集合中。

        6
  •  0
  •   harshit    17 年前

    开始在集合中添加向量的值。重写Class1和Class2的Equals方法,以决定如何使对象相等。如果不重写equals,则默认情况下将使用==进行比较,因为对象属于不同的类==将始终返回false。所以需要重写equals方法。

    推荐文章