【问题标题】:Unıque Random Number Check form Array c++唯一随机数检查表单数组c ++
【发布时间】:2021-03-17 20:52:46
【问题描述】:
#include <iostream>
#include<ctime>
#include<cstdlib>
#include<string>
#include<cmath>

using namespace std;

int main()
{
    bool cont = false;
    string str;
    int num, num2;
    cin >> str >> num;
    int arr[10];

    int a = pow(10, num);
    int b = pow(10, (num - 1));
    srand(static_cast<int>(time(NULL)));

    do {
        num2 = rand() % (a - b) + b;
        int r;
        int i = 0;
        int cpy = num2;

        while (cpy != 0) {
            r = cpy % 10;
            arr[i] = r;
            i++;
            cpy = cpy / 10;
        }

        for (int m = 0; m < num; m++)
        {
            for (int j = 0; j < m; j++) {
                if (m != j) {
                    if (arr[m] == arr[j]) {
                        break;
                    }
                    else {
                        cont = true;
                    }
                }
            }
        }
        cout << num2 << endl;
    } while (!cont);

    return 0;
}

我想从用户那里获取一个数字并产生这样一个随机数。

比如用户输入8,一个8位的随机数。这个数字必须是唯一的,所以每个数字必须互不相同,例如:

用户输入 5

随机数=11225(无效所以取新数)

随机数=12345(有效所以输出)

为此,我将数字分成数位并将其放入数组中并检查它是否唯一。程序从用户那里获取随机数并将它们扔到数组中。直到这一部分为止一切正常。但是我使用 for 循环检查这个数字是否唯一的函数不起作用。

【问题讨论】:

  • 45678 是5 的有效号码还是需要包含数字[1, entered_number]
  • 请更具体。 “但我得到一个错误”不是一个很好的描述。
  • 宁可使用 c++ 标准库中的Pseudo-random number generation。 IIRC 已经实现了生成唯一集和随机数范围的算法。
  • 有效,因为每个数字都不一样。
  • 这听起来像是针对唯一序列 0-9、随机洗牌和计数器的工作(如果前导数字为 0 则碰撞,因此被跳过)。

标签: c++ random


【解决方案1】:

因为您需要您的数字是唯一的,所以更容易预先保证唯一性,然后再混合使用。这里的问题解决原则是从你最受限制的地方开始。对您来说,这是重复的数字,所以我们确保这永远不会发生。这比验证我们是否这样做要容易得多。

此代码示例会将唯一编号打印到屏幕上。如果您需要将其实际存储在 int 中,则需要完成额外的工作。

#include <algorithm>
#include <iostream>
#include <numeric>
#include <random>
#include <vector>

int main() {
  std::vector<int> digits(10);
  std::iota(digits.begin(), digits.end(), 0);
  std::shuffle(digits.begin(), digits.end(), std::mt19937(std::random_device{}()));

  int x;
  std::cout << "Number: ";
  std::cin >> x;

  for (auto it = digits.begin(); it != digits.begin() + x; ++it) {
    std::cout << *it;
  }
  std::cout << '\n';
}

一些示例运行:

Number: 7
6253079

Number: 3
893

Number: 6
170352

向量digits 包含数字0-9,每个数字只出现一次。然后我把它们洗牌。然后根据用户输入的数字,打印第一个x 个位数。

此代码的一个缺点是第一个数字可能是 0,这可能符合您的规则,也可能不符合您的规则。如果不是,您将被限制为 9 位数字,std::iota 中的起始值将是 1

【讨论】:

    【解决方案2】:

    首先,我建议您在命名变量时做出更好的选择。你这样做:

        bool cont = false;
        string str;
        int num, num2;
        cin >> str >> num;
    

    什么是num和num2?给他们更好的名字。你为什么是cin >> str?我什至看不到你以后如何使用它。但我认为 num 是你想要的位数。

    您使用 a 和 b 的目的也完全不清楚。现在,我认为下一段代码是尝试创建一个数字。如果您要盲目尝试,然后在完成后,看看是否可以,为什么要让这个变得如此复杂。而不是这个:

        num2 = rand() % (a - b) + b;
        int r;
        int i = 0;
        int cpy = num2;
    
        while (cpy != 0) {
            r = cpy % 10;
            arr[i] = r;
            i++;
            cpy = cpy / 10;
        }
    

    你可以这样做:

     for(int index = 0; index < numberOfDesiredDigits; ++index) {
         arr[index] = rand() % 10;
     }
    

    我不知道你为什么要这么复杂。

    我认为这是您验证的代码:

        // So you iterate the entire array
        for (int m = 0; m < num; m++)
        {
            // And then you check all the values less than the current spot.
            for (int j = 0; j < m; j++) {
                // This if not needed as j is always less than m.
                if (m != j) {
                    // This if-else is flawed
                    if (arr[m] == arr[j]) {
                        break;
                    }
                    else {
                        cont = true;
                    }
                }
            }
        }
    

    您正在尝试确保没有重复项。如果第一个数字和第二个数字不同,则您正在设置cont == true,并且您一找到副本就会中断。我认为你需要重新考虑这一点。

    bool areAllUnique = true;
    for (int m = 1; allAreUnique && m < num; m++) {
        for (int j = 0; allAreUnique && j < m; ++j) {
            allAreUnique = arr[m] != arr[j];
        }
    }
    

    一旦我们遇到重复,allAreUnique 就会变为 false,并且我们会跳出两个 for 循环。

    那你就可以查了。

    请注意,我也是从 1 而不是 0 开始第一个循环。没有理由从 0 开始外循环,因为这样内循环就变成了无操作。


    更好的方法是保留一组有效数字——初始化为 1 到 10。然后在集合大小内抓取一个随机数,并从集合中抓取第 n 个数字并将其从集合中删除。您将在第一时间得到一个有效的结果。

    【讨论】:

    • 1 - 10 会重复数字 1。
    猜你喜欢
    • 1970-01-01
    • 2016-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多