具有反向相同数字的向量

vector of vector having reverse same numbers

本文关键字:数字 向量      更新时间:2023-10-16

如果我有一个向量向量,我们称之为:

vector<vector<int> > data;

在数据中,它有这样的数字

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

我怎样才能摆脱与自身相反的数据?例如:0 1 和 1 0,我想摆脱 1 0,因为我已经看到了 0 1。另一个例子:0 3 和 3 0,我想摆脱 3 0,因为我已经看到了 0 3。

所以数据将是这样的:

0 1
0 3
0 4
1 2
1 5

最简单的方法是什么?

您可以在集合中推送向量,并检查集合中是否已经存在反向向量。像这样:

C++11版本:

#include <iostream>
#include <vector>
#include <algorithm>
#include <set>
using namespace std;
vector<int> myrev(vector<int>& f)
{
  vector<int> s;
  s.push_back(f[1]);
  s.push_back(f[0]);
  return s;
}
int main()
{
  vector<vector<int> > data={{0,1},{0,3},{0,4},{1,0},{1,2},{1,5},{3,0},{1,0}};
  set<vector<int> > unique_data;
  for(auto& x: data)
  {
    if(unique_data.find(myrev(x))==unique_data.end())
      unique_data.insert(x);
  }
  for(auto& x: unique_data)
  {
    cout << x[0] << ":" << x[1] << endl;
  }
  return 0;
}

C++98版本:

#include <iostream>
#include <vector>
#include <algorithm>
#include <set>
using namespace std;
vector<int> myrev(vector<int>& f)
{
  vector<int> s;
  s.push_back(f[1]);
  s.push_back(f[0]);
  return s;
}
int main()
{
  vector<vector<int> > data;
  //lame C++98 initialization of the vector
  vector<int> tmp(2);
  tmp[0]=0;tmp[1]=1;
  data.push_back(tmp);
  tmp[0]=0;tmp[1]=3;
  data.push_back(tmp);
  tmp[0]=0;tmp[1]=4;
  data.push_back(tmp);
  tmp[0]=1;tmp[1]=0;
  data.push_back(tmp);
  tmp[0]=1;tmp[1]=2;
  data.push_back(tmp);
  tmp[0]=1;tmp[1]=5;
  data.push_back(tmp);
  tmp[0]=3;tmp[1]=0;
  data.push_back(tmp);
  set<vector<int> > unique_data;
  for(vector<vector<int> >::iterator x=data.begin(); x!=data.end(); x++)
  {
    if(unique_data.find(myrev(*x))==unique_data.end())
      unique_data.insert(*x);
  }
  for(set<vector<int> >::iterator x=unique_data.begin(); x!=unique_data.end(); x++)
  {
    cout << (*x)[0] << ":" << (*x)[1] << endl;
  }
  return 0;
}

由于您可能希望打印出没有相反值的值,因此您可以这样做:

for each pair:
    if it exists in the HashMap:
       do nothing
    else
        add the opposite to a HashMap 
        print the pair

如果您能够负担得起使用大量内存,并且整数的最大大小像您的示例一样很小,那么我将简单地创建一个足够大的位向量来容纳整个搜索空间。 从两个输入数字计算到此位向量的索引。

int N_POSSIBLE_PAIRS = (1 << MAX_BITS) * (1 << MAX_BITS);
// vector<bool> is specialized - it only uses 1 bit per entry
std::vector<bool> bitset(N_POSSIBLE_PAIRS);
int index = (first << MAX_BITS) | second;
// in a loop,
if (bitset[index]) {
    // duplicate
}
else {
    int reverse_index = (second << MAX_BITS) | first;
    bitset[index] = true;
    bitset[reverse_index] = true;
}

这实际上浪费了 2 倍的空间 - 如有必要,您可以使用更复杂的索引方案来修复它。

如果整数的最大大小太大,或者您的内存受到限制,或者您只是喜欢节俭内存,那么我会按字典顺序对对进行排序并使用二叉搜索来检查重复项。

我的建议也可能在稀疏数据上表现不佳,因为它对缓存不友好。

试试这个(假设列表中没有负数,并且出于空间原因,数字不会太大):

1) 创建一个大小为 MxM 的位集 2D 网格(其中 M 是预期的最大数字)。 将网格中的每个位设置为 0

2) 对于每对数字 (x,y):

check if grid(x,y) is 1.  If yes then you have a duplicate
else
check if grid(y,x) is 1.  If yes then you have a duplicate.
set grid(x,y) and grid(y,x) to 1