使用线性搜索为二维数组生成唯一数字

时间:2016-12-11 03:06:57

标签: c++ arrays algorithm multidimensional-array linear-search

程序编译,我可以输入一个数字,但它不会生成或显示数组。当我在randomFillUnique函数中使用线性搜索取出while条件时,它会生成并显示数组,但不会生成唯一数字。我需要一个没有重复数字的2D数组。

#include <iostream>
#include <string>
#include <random>
#include <ctime>
using namespace std;

int** gen2Array(int n);
void randomFillUnique(int** arr, int n);
bool lSearch(int** arr, int n, int target);
void display(int** arr, int n);

int main()
{
    int number;
    cout << "Enter a number: ";
    cin >> number;
    randomFillUnique(gen2Array(number), number);
    system("pause");
    return 0;
}
int** gen2Array(int n)
{
    int** arr2D = new int*[n];
    for (int index = 0; index < n; index++)
        arr2D[index] = new int[n];
    return arr2D;
}
void randomFillUnique(int** arr, int n)
{
    static default_random_engine e;
    uniform_int_distribution<int> u(1, n*n);
    e.seed(static_cast<int>(time(NULL)));

    bool result = false;
    for (int row = 0; row < n; row++)
    {
        for (int col = 0; col < n; col++)
        {
            arr[row][col] = u(e);   //generate random number
            result = lSearch(arr, n, arr[row][col]);
            while (result == true)
            {
                arr[row][col] = u(e);   //generate random number
                result = lSearch(arr, n, arr[row][col]);
            }
        }
    }
    display(arr, n);
    delete[] arr;
}
bool lSearch(int** arr, int n, int target)
{
    bool found = false;
    for (int row = 0; row < n; row++)
        for (int col = 0; col < n; col++)
        {
            if (arr[row][col] == target)
            {
                found = true;
                return found;
            }
        }
    return found;
}
void display(int** arr, int n)
{
    for (int row = 0; row < n; row++)
    {
        for (int col = 0; col < n; col++)
            cout << arr[row][col];
        cout << endl;
    }
}

3 个答案:

答案 0 :(得分:1)

因为你在搜索之前将数组中的条目设置为u(e),所以lsearch总是返回true而你的while会永远循环。以下,根据您的代码改编,应该修复(我假设其余代码的行为与人们预期的一样)。正如用户4581301所指出的那样,可能有更好的方法,但我希望与你的方法一起使用,我希望。

void randomFillUnique(int** arr, int n)
{
static default_random_engine e;
uniform_int_distribution<int> u(1, n*n);
e.seed(static_cast<int>(time(NULL)));
int nextEntry;
bool result = false;
for (int row = 0; row < n; row++)
{
    for (int col = 0; col < n; col++)
    {
        result = true;
        while (result == true)
        {
            nextEntry = u(e);   //generate random number
            result = lSearch(arr, n, nextEntry);
            if (result != true)
               {arr[row][col]=nextEntry;}
        }
    }
}
display(arr, n);
delete[] arr;
}

答案 1 :(得分:0)

另一种方法是使用iota创建一个包含所有唯一整数的容器,这些整数将进入数组:

std::vector<int> invalues(n*n, 0);
std::iota(invalues.begin(), invalues.end(), 1);

然后将那个容器洗牌:

std::shuffle(invalues.begin(), invalues.end(),
             std::mt19937{std::random_device{}()});

然后将这些值逐个输入矩阵。

您也可以使用vector<vector<int>>代替内置数组:

using matrix = std::vector<std::vector<int>>;

// initialising a vector<vector<int>> to be a certain size is a bit clumsy
matrix m(size_y, std::vector<int>(size_x, 0));

然后将输入值输入矩阵:

for (auto &row : m) {
  for (auto &elem : row) {
    elem = invalues.back();
    invalues.pop_back();
  }
}

然后显示矩阵:

for (const auto &row : m) {
  for (const auto &elem : row) {
    std::cout << elem << " ";
  }
  std::cout << std::endl;
}

Here's a full example in an online compiler.

答案 2 :(得分:0)

行。以下是我评论过的更简单的方法。如果不允许使用std :: vector,那么一个简单的1D向量就足够了,但是一个理智的软件工程师在通过vector选择之前会非常认真地思考。

我做了一些其他修改来解决其他一些错误。

#include <iostream>
#include <string>
#include <random>
#include <vector>
#include <algorithm> // std::shuffle and std::iota
#include <ctime>
using namespace std;

int** gen2Array(int n);
void randomFillUnique(int** arr, int n);
bool lSearch(int** arr, int n, int target);
void display(int** arr, int n);
//Added to properly delete the 2dArray
void del2Array(int ** arr, int n);

int main()
{
    int number = 10;
    randomFillUnique(gen2Array(number), number);
    system("pause");
    return 0;
}
int** gen2Array(int n)
{
    int** arr2D = new int*[n];
    for (int index = 0; index < n; index++)
        arr2D[index] = new int[n];
    return arr2D;
}

//Added to properly delete the 2dArray
void del2Array(int ** arr,
               int n)
{
    for (int index = 0; index < n; index++)
        delete arr[index];
    delete arr;
}
void randomFillUnique(int** arr, int n)
{
    //do the seeding here
    static default_random_engine e(static_cast<int>(time(NULL)));
// otherwise
//    e.seed(static_cast<int>(time(NULL)));
// runs every time reseeding the RNG to potentially the give the same results
// if run more than once in a second. Plus the seeding is expensive.

    std::vector<int> v(n*n); // make and size vector
    std::iota (v.begin(), v.end(), 0); // init vector with 1 through n*n
    std::shuffle(v.begin(), v.end(), e);

    size_t index = 0;
    for (int row = 0; row < n; row++)
    {
        for (int col = 0; col < n; col++)
        {
            arr[row][col] = v[index++];   //generate random number
        }
    }
    display(arr, n);
    del2Array (arr, n); // frankly I don't think you want his here
                        // why fill an array only to delete it?
                        // more logical to display and delete back in main.
}

void display(int** arr, int n)
{
    for (int row = 0; row < n; row++)
    {
        for (int col = 0; col < n; col++)
            cout << arr[row][col] << "\t"; //added a tab to make the printing easier to read
        cout << endl;
    }
}

Documentation on std::vector

Documentation on std::shuffle

Documentation on std::iota.其中正是使用此技术来演示iota。好笑,是吗?