检测2D阵列的列中的重复

时间:2013-07-23 17:35:34

标签: c++ algorithm

我想要一个通过2D数组的算法,并保证每列都有不同的数字。如果在阵列中发现了欺骗,则应使用随机数替换。随机数也必须保持唯一性。

如果我们输入一个随机数,整列,应该是唯一的。

是否也可以获得O(N)解决方案?

3 个答案:

答案 0 :(得分:1)

我能想到的最好的方法是为每列创建unordered_map<int,bool>,遍历列,如果第一次看到数字,则将地图设置为true,如果值已经为真,则为一个骗子用随机数替换它。然后检查地图中的随机数并做同样的事情,如果它也是一个骗局,你将不得不再用一个随机数替换它。这个算法会像线性时间一样运行,但是由于随机数欺骗的可能性,它可以无限运行。

伪代码

2d_array // assume M rows by N cols
array_of_hashtables // N length
for each col
    for each row
       if array_of_hashtables[2d_array[row][col]] == false
           set it to true
       else
           do
               set 2d_array[row][col] to random
           while array_of_hashtables[2d_array[row][col]] == true
    end
end

不是编写伪代码的忠实粉丝,但这是正确的

答案 1 :(得分:1)

制作std::set并在检查集合大小的同时逐步插入每列的元素。如果大小改变,插入的值不是重复的,如果它只是随机化一个值并再次将其添加到集合中。如果尺寸发生变化,您可以继续。

答案 2 :(得分:0)

只是为了它,这是Alexandru Barbarosie的解决方案的实现:

#include <iostream>
#include <set>
#include <cstdlib>
#include <ctime>

using namespace std;

int main()
{
    int L = 3;
    int W = 3;
    int R = 3;    
    int a[L][W];    
    srand(time(NULL));     
    for (int i = 0; i < L; i++)
    {
        for (int j = 0; j < W; j++)
        {
            a[i][j] = rand() % R + 1;
            cout << a[i][j] << " ";
        }
        cout << endl;
    }    
    cout << endl;

    set<int> s;    
    int n = 0;    
    for (int j = 0; j < W; j++)
    {
        for (int i = 0; i < L; i++)
        {
            s.insert(a[i][j]);
            if (s.size() != n)
                n = s.size();
            else
                a[i--][j] = rand() % R + 1;
        }
        s.clear();
        n = 0;
    }

    for (int i = 0; i < L; i++)
    {
        for (int j = 0; j < W; j++)
            cout << a[i][j] << " ";
        cout << endl;
    }
}