【问题标题】:Guaranteeing three digits in a randomly generated number保证随机生成的数字中的三位数字
【发布时间】:2018-02-27 04:33:56
【问题描述】:

我有一个作业要求我们生成一个三位数两次,以便学生可以将它们加在一起,然后检查他们的作业。我对 C++ 仍然非常非常陌生,遗憾的是,我的班级没有提供有关如何做到这一点的信息。他没有提供任何视频、文章或任何关于随机生成数字、如何确保特定数字的安全,甚至如何将它们相加的内容。

以下是我拼凑起来的代码,虽然很粗糙。我不能保证三位数。时不时地,它将是一个两位数的数字。我已经给他发了邮件,看看他能不能给我指出正确的方向,但我并不乐观。我在想有什么方法可以设置一个最小值,但是经过几个小时的搜索,我找不到答案。

#include "stdafx.h"
#include <iostream>
#include <cstdlib>
#include <ctime>

using namespace std;  //This is so I do not have to type std::

int main(void)
{
    int set1; 
    int set2;
    int sum=0;
    srand((unsigned) time(NULL)); // sets the random seed to provide different number utilizing the time of the computer

    set1 = rand() % 999 + 1; //creates a randomly generated three digit number
    set2 = rand() % 999 + 1; //created a randomly generated three digit number


    cout << "\n\n\n Are you ready for some math practice?\n\n\n";
    cout.width(8); //sets width of the columns to align everything
    cout << set1 << "\n"; //prints first generated set
    cout << " +   ";

    cout << set2 << "\n"; //[rints second generated set
    cout << "---------\n";
    cout << "\n\n\n";
    sum = set1 + set2; //add the two generated sets together
    cout << "Try to solve the problem. Have you got it?\n";
    system("Pause"); //waits for student to press enter to continue
    cout << "\n\n\n";
    cout << "The answer is: "; 
    cout << sum; //displays sum of two numbers

【问题讨论】:

  • 为什么不直接生成一个0到899之间的随机数,然后加100呢?
  • 你很接近:rand() % 999 将生成一个介于0998 之间的数字。相反,您可能应该在100898 (rand() % 899 + 100) 之间生成一个数字,然后添加100。有人可能会回答比我写的更好的混搭。

标签: c++


【解决方案1】:

常用的C方法

这就是你正在使用的。您需要三个信息:

  • 最小值。对你来说是 100。(前三位数字。)
  • 最大值。对你来说是 999。(最后三位数字。)
  • 范围,即(最大值 - 最小值 + 1)。对你来说,就是 (999 - 100 + 1) → 900。

要以 C 方法的方式计算它,请计算除以您的范围的余数并添加最小值。那就是:

set1 = rand() % 900 + 100;

任何以 900 为模的数字都会为您提供 0..899 的值。加 100,您会得到一个 100..999 中的数字。瞧!

正确C方法

上述方法存在偏差(感谢Pigeonhole Principle)。修复它的方法是简单地提取随机数,直到获得所需范围内的一个:

int random_in_range( int minimum, int maximum )
{
  int result;
  do result = rand();
  while (result < minimum || maximum < result);
  return result;
}

现在您可以简单地询问您想要的号码:

set1 = random_in_range( 100, 999 );

唯一需要注意的是非常小的范围(如 0..3)可能会产生明显的滞后;你会想要更复杂一点。 (比如求0..399中的数字除以100。)

C++ 方法

既然你用的是C++,不妨学习一下如何正确使用。

#include <chrono>
#include <random>

int random_in_range( int minimum, int maximum )
{
  thread_local std::ranlux48 rng( 
    std::chrono::system_clock::now().time_since_epoch().count() );
  return std::uniform_int_distribution <int> ( minimum, maximum )( rng );
}

...

set1 = random_in_range( 100, 999 );

这里我们使用一个静态的(线程安全的——如果你只有一个线程,只需使用单词static而不是thread_local)伪随机数生成器,我们使用均匀整数分布从中得到一个数字在所需的最小值和最大值给定的范围内。

这一切都包含在一个方便的函数中,因此在使用它时看起来与在 C 版本中相同,但它在以下方面要好得多:

  • 偏见
  • 速度
  • 质量

在所有情况下...

您可以以同样的方式使用现有代码:生成两个随机的三位数字,要求用户输入他们的总和,然后将他的答案与您的答案进行比较。

【讨论】:

【解决方案2】:

你非常接近!

set1 = rand() % 999 + 1; //creates a randomly generated three digit number

这实际上会在1999 之间生成一个随机数。你想要的是在100999之间生成一个数字,最简单的方法是在0899之间生成一个数字,然后添加100

set1 = rand() % 900 + 100; //creates a randomly generated three digit number

rand() 适合您的目的,但您可以使用uniform_int_distribution 使这一点更加清晰并获得更好的结果

#include <random>
#include <iostream>

int main()
{
    std::random_device rd;
    std::mt19937 gen(rd());
    std::uniform_int_distribution<> dis(100, 999); // our distribution is between 100 and 999
    // print 100 random numbers to test
    for (int i = 0; i < 100; ++ i)
        std::cout << dis(gen) << "\n";
}

【讨论】:

    猜你喜欢
    • 2013-05-05
    • 2014-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-08
    • 1970-01-01
    • 2018-01-25
    • 1970-01-01
    相关资源
    最近更新 更多