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

detecting duplicate in columns of a 2D array

本文关键字:阵列 检测 2D      更新时间:2023-10-16

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

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

有可能得到O(N)溶液吗?

我能想到的最好的方法是为每列生成一个unordered_map<int,bool>,遍历该列,如果你第一次看到一个数字,则将映射设置为true,如果该值已经为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

不太喜欢写伪代码,但这是关于正确的

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

下面是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;
    }
}