如果 {x,y} 和 {y,x} 也被认为是相同的,那么删除 vector<pair<A,A> > 中重复项的最简单方法是什么?

What is the simplest way to remove duplicates in vector<pair<A,A> > if {x,y} and {y,x} are also considered as identical?

如果 2 对 {x,y} 和 {y,x} 也被认为是重复的,是否有内置方法删除对向量的重复项?

例如,如果我有这样的矢量:

{{1,2},{4,3},{2,1},{5,6},{1,2},{3,4},{0,1}}

我想删除重复项成为:

{{1,2},{4,3},{5,6},{0,1}}

是否有任何内置函数来处理 {x,y} 和 {y,x} 相同的情况?

如果没有,最简单的方法是什么?

我考虑过使用 for 循环类似的东西但不起作用:

vector<int> isRemove;
int count=0;
for(pair<int,int> a : p){
    isRemove.push_back(0);
    for(pair<int,int> b : p){
        if((a.first==b.first && a.second==b.second) || (a.first==b.second && a.second==b.first)){
            isRemove[count]=1;
            break;
        }
    }
    count++;
}
for(int i=isRemove.size()-1;i>=0;i--){
    printf("%d\n",isRemove[i]);
    if(isRemove[i]){
        p.erase(p.begin()+i);
    }
}

还有更简单的方法吗?

std::set holds unique values. Uniqueness is determined by a comparator. You can implement your desired solution as follows (live example):

#include <algorithm>
#include <iostream>
#include <set>
#include <vector>

struct custom_comparator {
    bool operator()(const std::pair<int, int>& a,
                    const std::pair<int, int>& b) const
    {
        return less_comparator(std::minmax(a.first, a.second),
                               std::minmax(b.first, b.second));
    }

    std::less<std::pair<int, int>> less_comparator;
};

int main() {
    // Input data including some duplicates
    std::vector<std::pair<int, int>> a = {
        {1, 2}, {4, 3}, {2, 1}, {5, 6}, {5, 6}, {6, 5}, {1, 2}, {3, 4}, {0, 1}
    };

    // Specify custom comparator for the set
    std::set<std::pair<int, int>, custom_comparator> unique;

    // Fill the set
    for (const auto& p : a) {
        unique.insert(p);
    }

    // Demonstrate uniqueness by outputting the elements of the set
    for (const auto& p : unique) {
        std::cout << p.first << ", " << p.second << "\n";
    }

    return 0;
}

输出:

0, 1
1, 2
4, 3
5, 6

您只需定义一个带有自定义比较器的集合,以确保在调用 std::less 时每对中的顺序一致,然后填充该集合。

#include <vector>
#include <algorithm>
#include <iostream>
int main(){
  using namespace std;
  using Intpair = std::pair<int,int>;

  vector<Intpair> v = {{1,2},{4,3},{2,1},{5,6},{1,2},{3,4},{0,1}};
  //Normalize == sort the pair members
  for(auto& p : v){
    int x = max(p.first, p.second), y = min(p.first, p.second);
    p.first = x; p.second = y;
  }
  //Sort the pairs
  sort(v.begin(), v.end(),[](Intpair x, Intpair y){ return (x1 < y1) || (x1==y1 && x2<y2); }  );

  //Print the vector in its normalized and sorted form
  for(auto p : v){ cout<<p.first<<' '<<p.second<<'\n'; }
  cout<<'\n';
  //Unique the vector
  auto last = unique(v.begin(), v.end() );
  v.erase(last, v.end());

  //Print the unique'd vector
  for(auto p : v){ cout<<p.first<<' '<<p.second<<'\n'; }
}

输出:

1 0
2 1
2 1
2 1
4 3
4 3
6 5

1 0
2 1
4 3
6 5

与使用 std::set 相比,对于较小的向量,这应该具有更好的性能,因为后者不像向量那样对缓存友好。

以下程序将完全满足您的需要:

#include <iostream>
#include <vector>


int main () {
  std::vector<std::pair<int, int>> myvector;
  myvector.push_back(std::make_pair(1,2));
  myvector.push_back(std::make_pair(4,3));
  myvector.push_back(std::make_pair(2,1));
  myvector.push_back(std::make_pair(5,6));
  myvector.push_back(std::make_pair(1,2));
  myvector.push_back(std::make_pair(3,4));
  myvector.push_back(std::make_pair(0,1));

  auto it = myvector.begin();
  for (; it != myvector.end(); ++it) {
      auto pit = myvector.begin();
      for (; pit != myvector.end();) {
          if (((it->first == pit->first && it->second == pit->second) || (it->first == pit->second && it->second == pit->first)) && (pit != it)) {
              std::cout << "found pair " << it->first << "," << it->second << " with " << pit->first << "," << pit->second << std::endl;
              pit = myvector.erase(pit);
          } else {
              ++pit;
          }
      }

  }

  std::cout << "myvector contains:";

  for (it=myvector.begin(); it!=myvector.end(); ++it)
    std::cout << ' ' << it->first << "," << it->second;

  std::cout << '\n';

  return 0;
}

输出:

myvector contains: 1,2 4,3 5,6 0,1