生成介于10到65之间的随机数

3
我希望我的程序能够生成500个10到65范围内的随机数。请问如何实现?
目前,我的程序会生成0到74之间的随机数。同时,我发现最高值和最低值显示的并不是生成的随机数,而是随机数的范围。以下是我的代码:

#include<iostream>
#include<exception>
#include<stdlib.h>   
using namespace std;

int main(){
    int year;
    int nextLine = 20;
    int highestValue = 0;
    int lowestValue = 0;
    int ages[500];
    int range = 65;

    cout << "Enter year today: ";
    cin >> year;
    srand(year);

    cout << "The ages are: \n";
    for (int i = 0; i < 500; i++){
        ages[i] = rand() % 65 + 10;
        cout << ages[i] << " ";

        if (i + 1 == nextLine){
            cout << "\n";
            nextLine += 20;
        }
    }

    for (int j = 0; j < 500; j++){
        if (ages[j] > highestValue)
            highestValue = ages[j];

        if (ages[j] < lowestValue)
            lowestValue = ages[j];
    }

    cout << "\nRange(HV-LV): " << highestValue << " - " << lowestValue << " = " << highestValue - lowestValue;

    system("pause>0");
    return 0;
}

编辑: 这是一个包括范围的可工作代码。:)

#include<iostream>
#include<exception>
#include<algorithm>
using namespace std;

int main(){
    int year;
    int nextLine = 20;
    int highestValue;
    int ages[500];
    int lowestValue;
    int range = 65;

    cout << "Enter year today: ";
    cin >> year;
    srand(year);

    cout << "The ages are: \n";
    for (int i = 0; i < 500; i++){
        ages[i] = rand() % 56;
        ages[i] += 10;
        cout << ages[i] << " ";

        if (i + 1 == nextLine){
            cout << "\n";
            nextLine += 20;
        }
    }

    highestValue = *max_element(ages, ages + 500);
    lowestValue = *min_element(ages, ages + 500);

    cout << "\nRange(HV-LV): " << highestValue << " - " << lowestValue << " = " << highestValue - lowestValue;

    system("pause>0");
    return 0;
}

3
在C++11中,std::uniform_int_distribution<int> distribution(10, 65); 可能会有所帮助。 - Jarod42
4个回答

2

将此更改为:

ages[i] = rand() % 65 + 10;

到这个:
ages[i] = rand() % 56;
ages[i] += 10;

谢谢!它有效了!但应该是ages[i] = rand() % 56; - Mariel
你可以详细解释一下这个答案吗?特别是为什么要将它分成两行? - Glenn Teitelbaum
当他执行rand() % 65+10时,就像他正在执行rand()%75,它返回[0,74]。但是当更改为rand()%56时,它将返回[0,55],并在其上加10变成[10,65]。 - pedro
2
取余运算符的优先级高于加法。将代码拆分成两行有什么区别? - Jordan Melo
1
括号也可以,而且可能更好地显示原始问题。 - SirGuy

2

您原来的代码没有产生您所期望的结果,有两个原因。

1)ages[i] = rand() % 65 + 10; 应该改为 ages[i] = rand() % 56 + 10;

但是您已经知道了这一点 :)

2)当您计算最低值时,您设置了int lowestValue = 0;,但在测试中

if (ages[j] < lowestValue)
    lowestValue = ages[j];

你可以明显地看到,你的年龄值不可能小于零,因此lowestValue永远不会被更新。但是,如果你检查打印输出,它会显示你的任何值都不会低于10。
如果你使用int lowestValue = std::numeric_limits<int>::max()代替int lowestValue = 0并包括#include <limits>,你应该会得到预期的结果。
这就是为什么当你使用min_elementmax_element时没有看到问题的原因 :)

1
一旦您生成了随机数,假设在0到74的范围内,但您需要它们在10到65的范围内,您只需通过转换即可。
x = y * (55.0/74.0) + 10;

更一般地,如果y在[ymin,ymax)范围内,而你需要x在[xmin,xmax)范围内,则可以通过以下方式获得:
x = (y-ymin) * ( (xmax-xmin)/(ymax-ymin) ) + xmin;

已经有一个(更好的)答案了,只是想提一下。


2
这对于更改浮点数的范围非常有效,但对于整数来说,由于四舍五入,它可能会极大地改变随机数的分布。例如,如果您将范围从0-20更改为0-16,则在该范围内,0、3、6、9和12的数量将是其他数字的两倍。 - Jordan Melo
@JordanMelo 很好的观点。我完全没有想到过。所以这个回答实际上是值得发布的 ;) - 463035818_is_not_a_number

1

问题不在于rand() % x + y
正如Jordan Melo所指出的那样,余数(%)的优先级高于加法(+)。拆分文本对计算没有影响。

问题在于你的lowestValue=0,这是不正确的。你的rand()表达式生成的值都不可能低于0。

注意观察输出结果有助于解决问题。注意到所有输出值都不小于10。这说明你的rand()表达式是正确的。

你修改后的代码也是不正确的
在修改后的代码中,你将lowestValuehighestValue改成了未初始化的值。这意味着你的代码可能会或者可能不会工作。

为了找到最大值,初始最大值必须是可能的最小值。
为了找到最小值,初始最小值必须是可能的最大值。

int lowestValue = 74;
int largestValue = 10;

希望这有所帮助。

未初始化的变量并不是问题,因为在修改后的代码中,Mariel使用max_elementmin_element来计算范围。在读取它们之前,确实已经初始化了highestValuelowestValue(使用这两个函数的结果)。 - Jordan Melo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接