从两个向量中删除垂直反转重复项
Remove vertical reversed duplicates from two vectors
我用两列填充文本文件中的两个向量:
while (infile >> a >> b) {
Alist.insert(Alist.end(), a);
Blist.insert(Blist.end(), b);
}
到目前为止一切顺利,这些向量包含如下数字:
Alist Blist
1 6
1 4
2 4
2 7
2 5
2 3
3 9
3 2
3 5
4 1
4 6
5 3
5 2
5 8
5 9
6 4
6 1
7 2
8 5
8 9
9 3
9 5
9 8
我想删除其中一对夫妇,例如1 6
6 1
.我希望删除6 1
。像1 4
4 1
这样的夫妻更多。我怎样才能做到这一点?
刚刚做了这个:
int g = 0, h =0;
for (int i = 0; i < Alist.size(); i++) {
g = Alist[i];
h = Blist[i];
for (int y = 0; y < Blist.size(); y++) {
if (Blist[y] == g && Alist[y] == h) {
Alist.erase(Alist.begin() + y);
Blist.erase(Blist.begin() + y);
}
}
}
正如其他人所建议的,一种可能的方法是使用std::map
对来确保唯一性(一旦给出了比较函数)。您可以在将一对添加到容器之前测试重复项,避免之后的搜索和擦除。
#include <set>
using pair_int = std::pair<int,int>;
struct comp_pair {
constexpr bool operator()(const pair_int &lhs, const pair_int &rhs) const {
// compare the two pairs by their elements
return lhs.first < rhs.first ? true : (
lhs.first == rhs.first && lhs.second < rhs.second ? true : false);
}
};
std::set<pair_int,comp_pair> ABlist;
while ( std::cin >> a >> b ) {
// Assuming that A list is sorted, only pairs in which a > b can already
// be present in the container as a (b,a) pair
if ( a > b && ABlist.find(std::make_pair(b,a)) != ABlist.end() )
// if there is a match, go on without inserting anything
continue;
// insert a pair. The container grants for uniqueness
ABlist.insert(std::make_pair(a,b));
}
此代码段在包含您提供的输入示例的测试程序中生成以下输出:
1 4
1 6
2 3
2 4
2 5
2 7
3 5
3 9
4 6
5 8
5 9
8 9
基于初始代码的首次改进
您的代码没有考虑到Alist[i]==Blist[i]
的情况,这种情况总是被消除。 它还错过了多个相同的对,因为它没有考虑到当前位置随着擦除移动到下一个项目。 在最坏的情况下,随着矢量的缩小,它甚至可能超出内部循环的范围。
请注意,i
之前的反向对项目已被删除。您可以使用它来提高算法的稳定性,方法是在当前位置之后开始搜索反转的:
for (int i = 0; i < Alist.size(); i++) {
int g = Alist[i];
int h = Blist[i];
for (int y = i+1; y < Blist.size(); ) { // start with next
if (Alist[y] == h && Blist[y] == g) {
Alist.erase(Alist.begin() + y);
Blist.erase(Blist.begin() + y);
}
else y++; // move to next only if current one was not erased
}
}
AList
已经排序的事实(根据您的评论)确保对于 1 6 和 6 1,第二个将被消除:
你可以通过利用排序Alist
来进一步改进:在超过目标时停止内部循环,并且只有在有机会找到某些东西时才进入循环,即如果 h>=g:
if (h>=g)
for (int y = i+1; y < Blist.size() && Alist[y]<=h; ) { // start with next, stop if over target
...
}
在线演示
进一步改进
您最终可以通过使用二叉搜索来查找Blist[i]
在Alist
中首次出现,从而进一步改进。 但是,保留先前修剪方法的优点,并将此ony用作内部for循环中y的起始值。
相关文章:
- 将数组的地址分配给变量并删除
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- C/C++编译器通常会删除重复的库吗
- 从链接列表c++中删除一个项目
- C++如何通过用户输入删除列表元素
- 为什么在C++中使用私有复制构造函数与删除复制构造函数
- 是否需要删除包含对象的"pair"?
- 如何在自删除后将对象设置为nullptr
- 迭代时从向量和内存中删除对象
- 使用函数"remove"删除重复元素
- 如何从多映射中删除特定的重复项
- 运算符C++ "delete []"仅删除 2 个前值
- 删除指向指针的指针是运行时错误吗
- 将指针设置为"nullptr"并不能防止双重删除?
- 为什么示例代码访问IUnknown中已删除的内存
- 如何通过 getter 函数删除矢量的元素?
- 从控制台中删除最后打印的元素
- C 如何删除垂直滚动条
- 从两个向量中删除垂直反转重复项
- 如何删除QStandardItemModel中的垂直标题