矢量具有反向相同的数字

时间:2014-04-01 17:30:11

标签: c++ vector

如果我有矢量矢量,请调用它:

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

最简单的方法是什么?

4 个答案:

答案 0 :(得分:1)

由于您可能希望打印出没有对立面的值,您可以这样做:

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

答案 1 :(得分:1)

如果你可以负担得起使用大量内存,并且整数的最大大小很小,就像你的例子一样,我只需要创建一个足够大的位向量来保存整个搜索空间。从两个输入数字计算此位向量的索引。

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倍的空间 - 如果需要,您可以使用更复杂的索引方案来解决这个问题。

如果整数的最大大小太大,或者你的内存受限,或者你更喜欢节省内存,那么我会按字典顺序对这些对进行排序并使用二进制搜索来检查是否有重复。

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

答案 2 :(得分:1)

您可以按下一组中的向量,并检查该组中的反向是否已经存在。像这样:

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;
}

答案 3 :(得分:0)

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

1)创建一个大小为MxM的bitset 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