【问题标题】:Remove duplicate vectors inside a vector of vector删除向量向量中的重复向量
【发布时间】:2011-11-29 09:20:00
【问题描述】:

我有一个包含整数值的向量 (loops)。一些内部向量是重复的,但它们的元素顺序不同。现在,我想得到一个向量的向量,而没有任何重复的内部向量。 这是我的 vec 的示例;

循环 = ((9 18 26 11 9), (9 11 26 18 9),(9 18 25 16 9),(11 45 26 11),(11 26 45 11),(16 49 25 16) ,(16 25 49 16),(18 9 11 26 18),(18 9 16 25 18),(25 16 49 25),(26 11 45 26))

识别任何内部向量是否是另一个内部向量的副本;我开发了一个函数IsDuplicate。这告诉我,(9 18 26 11 9) and (9 11 26 18 9) 是重复的,然后我可以删除第二个或所有其他重复。

为了删除我的向量向量中的重复向量,我实现了以下代码。

Vector<vector<int> > loops;
Vector<vector<int> > ::iterator no1, no2;
Int setno1, setno2;

for (no1=loops.begin(), setno1=0; no1!=loops.end(); no1++, setno1++){
       set1 = *no1;
       for (no2=loops.begin()+setno1, setno2=setno1; no2!=loops.end(); setno2++){
            set2 = *no2;
            if (set2.IsDuplicate(set1))  loops.erase(loops.begin()+setno2);
            else no2++;
       }

  }

花了很长时间,我认为我的程序正在崩溃。所以,请帮我纠正这个问题。

另外,我试过这个。这有效,但我得到了错误的答案。请帮忙。

01   int first=0; bool duplicates=false;  
02   do {     
03        set1 = loops[first];     
04        for (no2=loops.begin()+1, setno2=1;  no2!=loops.end();  setno2++){     
05             set2 = *no2;      
06             if (set2.IsPartOf(set1)){      
07                 loops.erase(loops.begin()+setno2);     
08                 duplicates = true;      
09             }      
10             else no2++;     
11        }      
12        first++;      
13       } while(!duplicates); 

【问题讨论】:

  • “崩溃”怎么办?未捕获的异常?可能是分段错误?
  • 为什么不制作集合或多重集合的向量?那么识别重复项会容易得多。甚至是一组集合。
  • @KerrekSB 集合 (1,1,2) 和 (1,2,2) 是否相等?

标签: c++ vector iterator


【解决方案1】:

惯用的方法是将Erase/Remove idiom 与自定义谓词一起使用。 要检查重复向量而不修改向量的内容,请编写一个按值获取参数的谓词,对向量进行排序并使用std::equal

bool equal_vector(std::vector<int> a, std::vector<int> b) {
  std::sort(a.begin(), a.end());
  std::sort(b.begin(), b.end());

  return std::equal(a.begin(), a.end(), b.begin());
}

// use it like this
v.erase( remove_if(v.begin(), v.end(), equal_vector), v.end() );

至于您当前代码失败的原因:从vector 中删除一个元素会使当前存在的该向量的所有其他迭代器无效,因此vector::erase 将一个有效的迭代器返回到已删除元素之后的位置。

stdlib 还提供了 setmultiset 容器,它们看起来更适合您的目的。

【讨论】:

  • 感谢您的回复。但是我,我使用的是 DevC++,我不能使用惯用方式(我之前尝试使用这种方式来删除向量内的元素,但可以这样做。所以我希望开发人员无法识别这些惯用语。),如果可以,请添加做同样事情的传统方式。然后,我可以学习和实施。另外,我不能使用 set,因为我真正的 objct 类不是整数(它是我自己的类 PointNumber),而是从整数继承并为简单起见发布为整数。 - 提前致谢-
  • @g_niro 我没有使用 DevC++ 的经验,但这似乎是不可能的。您是否包含正确的标题?您至少需要 algorithmvector 才能使上述内容正常工作。如果algorithm 标头不支持removesort,您应该尽快切换到可行的平台。
  • @g_niro 只要 PointNumber 定义了 operator&lt;intPointNumber 的区别也不会影响该代码。
  • @g_niro 所以,我不明白是什么让这个解决方案无法为你工作。您可能想在单独的问题中向我们展示代码和错误。
  • 对不起,我可以说你,我不能改变我的元素顺序,因为我以后需要这个排序值。 (我猜,没办法使用排序)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-06-12
  • 1970-01-01
  • 2011-01-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多