如何查找2D矢量是否包含重复行?

时间:2017-09-09 19:27:16

标签: c++ multidimensional-array vector duplicates

我想要一种优雅的方法来检查是否

(myvector[0][1] != myvector[1][1] != myvector[2][1]) && (myvector[0][0] != myvector[1][0] != myvector[2][0])

等等。我知道这不是你如何将值与if语句进行比较...我认为将变量存储到向量中将是正确比较值的最快方法,因为有很多变量不能彼此相等

编辑:也许我不是那么清楚,基本上我希望[x] [0],[x] [1]永远不会匹配[y] [0],[y] [1] ...如果[0]或[1]是不同的,那么它很好但如果两个配对中的任何一个匹配,则返回false。

{0,0},
{1,1},
{0,1}

没问题,因此通过了重复测试

{0,0}, 
{1,1},
{0,0}

失败,因为有两对0,0

之所以如此,是因为第一行的值介于2-14之间,第二行的值介于0-3之间。这些值代表52张牌,我不想重复卡片

3 个答案:

答案 0 :(得分:1)

使用map。如果元素存在于地图中,它将占用O(N)空间和O(LogN)来搜索元素。 map.find()有助于在LogN时间内找到地图中的元素。在您的情况下,元素可以是pair

以下是示例代码:

#include <iostream>
#include <map>
using namespace std;
int main() {
    int i,j,n=3,m=2;
    for(i=0;i<n;i++)
    {
       for(j=0;j<m;j++)
            cin>>a[i][j];
    }
    map< pair<int,int>,bool>m;        // Map key can be a pair and value can be boolean 
    bool unique = true;
    for(i=0;i<n;i++)
    {
        if(m.find(make_pair(a[i][0],a[i][1]))==m.end())    // if pair is not already present in array insert the element in map
            m[make_pair(a[i][0],a[i][1])]=true;
        else        
        {
            unique=false;    // else pair was already present in array
            break;           // break the loop
        }
    }
    if(unique)
        cout<<"true";
    else cout<<"false";
    return 0;
}

Input:
0 0
1 1
0 1
Output:
true

Input:
0 0
1 1 
0 0
Output:
false

答案 1 :(得分:1)

由于您代表的是一副牌,您是否考虑过使用带有位组的枚举?有了它,您可以将卡的组合存储到一个数字中,并轻松比较它们。如果大集超过int的精度(int有32位),请使用std::bitset<N>,其中N是集合中的项目数。< / p>

#include <iostream>

enum Deck
{
    Jack =  2 << 0,
    Queen = 2 << 1,
    King  = 2 << 2,
    Ace   = 2 << 3
};

void compare_hands(const int hand1, const int hand2)
{
    if (hand1 == hand2)
        std::cout << "Same hand" << std::endl;
    else
        std::cout << "Different hand" << std::endl;
}

int main()
{
    int hand1 = Jack  | Queen;
    int hand2 = King  | Ace;
    int hand3 = Queen | Jack;

    compare_hands(hand1, hand2);
    compare_hands(hand1, hand3);
    compare_hands(hand2, hand3);

    return 0;
}

答案 2 :(得分:1)

这里是使用std :: vector vs std :: map的简单解决方案的基准(在另一个答案中)。你可以在这里看到矢量解决方案快6倍(对于一个小数据集):

http://quick-bench.com/-fOG_uDO6HRPKqOMgxqchqUXHbo

#include <iostream>
#include <algorithm>
#include <benchmark/benchmark.h>
#include <memory>
#include <vector>

constexpr int width=2;
constexpr int height=16;

static void vector(benchmark::State& state) {
    std::vector<std::vector<int>> data;

    int count = 0;
    for(int i = 0; i < height; i++) {
    data.emplace_back(std::vector<int>());
    for (int j = 0; j < width; j++) {
        data[i].push_back(count++);
    }
    }
    while (state.KeepRunning()) {

    std::vector< std::pair<int,int>>m;        // Map key can be a pair and value can be boolean
    m.reserve(height);
    bool unique = true;
    for(int i=0;i<height;i++)
        {
        if(std::find(m.begin(), m.end(), std::make_pair(data[i][0],data[i][1]))==m.end())    // if pair is not already present in array insert the element in map
            m.emplace_back(std::make_pair(data[i][0],data[i][1])); // nothing to do here
        else
            {
            unique=false;    // else pair was already present in array
            break;           // break the loop
            }
        }
    if(!unique) {
        std::cout<<"unexpected match found";
    }

    }

}
BENCHMARK(vector);

static void set(benchmark::State& state) {
    std::vector<std::vector<int>> data;

    int count = 0;
    for(int i = 0; i < height; i++) {
    data.emplace_back(std::vector<int>());
    for (int j = 0; j < width; j++) {
        data[i].push_back(count++);
    }
    }

    while (state.KeepRunning()) {

    std::map< std::pair<int,int>,bool>m;        // Map key can be a pair and value can be boolean
    bool unique = true;
    for(int i=0;i<height;i++)
        {
        if(m.find(std::make_pair(data[i][0],data[i][1]))==m.end()) {    // if pair is not already present in array insert the element in map
            m[std::make_pair(data[i][0],data[i][1])]=true;
        } else {
            unique=false;    // else pair was already present in array
            break;           // break the loop
        }
        }
    if(!unique) {
        std::cout<<"unexpected duplicate found";
    }
    }
}
BENCHMARK(set);

更改使用std::unordered_map的代码会让情况变得更糟 - 比std::vector慢10倍:http://quick-bench.com/aSKrpaW4cZoL2mYJFjy6x1dEvDo

(虽然我的表现可能很差)

可能会在地图解决方案上进行一些优化,但仍然无法使用此大小的数据集更快地使地图解决方案。

这两种算法似乎在大约250对中均匀,但也可以对矢量解决方案进行进一步的优化,以使其更好地扩展。