我从一个包含两列的文本文件中填充两个向量:
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);
}
}
}
答案 0 :(得分:1)
正如其他人所建议的,一种可能的方法是使用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
答案 1 :(得分:0)
第一项改进,基于您的初始代码
您的代码没有考虑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的起始值。