如何用一个范围内的随机值填充数组?(可允许重复)

3

我是新手学习C++,我遇到了一个数组操作的问题。我有一个长度为100的X数组,我需要随机地填充X的值为整数1到10(1,2,3,4,5,6,7,8,9,10)。

我知道会有重复的数字,例如可能会出现10个1之类的情况,但这正是我想要的。

以下是我的代码:

X数组如下:

int X[100];

以下是我的代码片段:

int* X = NULL;
int* val = NULL;
int length1= 100;
int length2= 10;
X = new int[length1];
val = new int[length2];
int i;
int j;

for (i = 0; i < isi; i++) {
    val[i] = i;
    for (j = 0; j < length1; j++) {
        if (j > i) {
            X[j] = val[i];
        } else {
            X[j] = val[0];
        }
        cout << "X[" << j << "] = " << X[j] << "\n";
        Sleep(1);
    }
}

上面的代码使数组X从索引0到99的值为0,然后索引0到99的值为1,直到其他索引的值都是9。

这不是我想要的,我想要的是(如果不是随机的)索引0到9的值为0,然后10到19的值为1,一直到索引90到99的值为9。希望我的解释清楚。

我在stackoverflow上提出了一个问题: 如何使用1-1000(包括1和1000)的值创建一个长度为10000的数组?

但我自己还是解决不了我的问题。

请有人给我一个解决方案。

提前感谢您!


1
C++有std::generate和均匀分布。 - chris
@user2864740 我尝试在循环内部使用嵌套循环,并将数组值设置为其循环变量,这样可以实现吗?我将添加我的代码片段到问题中以使其更清晰。 - codelop
已经完成了,@user2864740,希望我的解释清晰明了,你能帮忙吗 :) - codelop
我没有看到任何“随机”的情况发生。 - user2864740
@user2864740,你能否给我一小段代码片段,可以回答中给我。我对C++中的这个问题真的很新。 - codelop
显示剩余6条评论
5个回答

9
#include <stdlib.h>

int main(int argc, char **argv) {
  int r[100];
  for (int i = 0; i < 100; ++i) {
    r[i] = rand() % 10 + 1;
  }
}

对于某些输出,您可以在循环中的每次分配之后包含#include <iostream>,然后使用std::cout << "r[" << i << "] = " << r[i] << "\n"

如果要为每个不同的序列设置随机数生成器种子,则需要#include <time.h>,然后在第一次调用rand之前使用srand(time(NULL))


谢谢Darren Stone,我会尝试的。如果我想按随机数升序排序怎么办? - codelop
恕我直言,在互联网和 StackOverflow 上已经有足够的解释来说明如何在 C++ 中对整数数组进行排序。它很容易被找到。我希望上面提供的随机数组代码能够回答你的问题。 - Darren Stone
谢谢@Darren Stone,你的回答确实有帮助,但我只能选择一个答案,我选择user2864740的答案,因为他提供了学习经验和伪代码。谢谢。 - codelop

8
您可以使用generate函数:
#include <iostream>
#include <algorithm>
#include <random>

using namespace std;

int main()
{
    int arr[100];
    random_device rd;
    default_random_engine dre(rd());
    uniform_int_distribution<int> uid(0,9);

    generate(arr, arr + sizeof(arr) / sizeof(int), [&] () { return uid(dre); });

    for (int a : arr)
        cout << a << " "; 
}

谢谢您的建议,但是由于我使用的是minGW,'random_device'似乎无法在这里使用,谢谢。 - codelop
它是标准库的一部分,因此应该可以使用(您必须include <random>,或尝试std::random_device)。 - w.b
是的,我在另一个项目中尝试过,但是MinGW编译器似乎还不支持它。以下是错误消息: error: #error This file requires compiler and library support for the ISO C++ 2011 standard. This support is currently experimental, and must be enabled with the -std=c++11 or -std=gnu++11 compiler options - codelop

5
这里有两种解决问题的方法 - 由于这是一个学习经验,因此仅提供伪代码(和相关链接)。每个“任务”都可以单独查找和解决。请注意,两种方法都不使用辅助数组。
如果最终结果中每个数字的数量不需要相同(例如,数字2可能出现17次),那么考虑以下循环和随机赋值方法。标准的C for-each循环足以实现。
# for every index pick a random value in [0, 10) and assign it
for i in 0 to last array index:
    array[i] = random in range 0, 10

如果需要数字的数量相同,则考虑填充数组,然后对其进行洗牌。在此处,模运算符非常方便。(假设数组长度是组大小的倍数。)
# fill up array as 0,1,2,3,4,5,6,7,8,9,0,1,2.. (will be 10 groups)
for i in 0 to last array index:
    array[i] = i % 10
# and randomly rearrange order
shuffle array

对于洗牌,请参见Fisher-Yates,其中甚至展示了C实现-虽然有"更多的C++"方法,但这是一个学习和练习循环的好技巧。 (Fisher-Yates的一个酷属性是,一旦项目被交换到当前索引中,它就在最终交换位置上 - 因此可以修改洗牌循环以同时进行洗牌立即执行诸如显示值之类的操作。)

在两种情况下都应使用随机函数; 否则数字将不会是..随机的。


非常感谢,它起作用了,也感谢通过伪代码提供的学习经验。我选择这个答案来帮助我,因为它很有用,谢谢@user2864740 :) - codelop

0
我认为其他人已经指出了,但你必须首先编写预编译器指令#include <ctime>,然后使用srand函数。 大多数人会说不要使用它,但由于你和我都处于基础阶段,我们的老师分别为我们提供了该功能。 它也可能适用于您的编译器。 这是一个学习更多信息的链接。 我本来想评论的,但我不能。 http://www.cplusplus.com/reference/cstdlib/srand/

0

在C++中,遍历集合中的项最自然的循环方式是范围-based for循环。

为了将某些内容分配给每个项,形式上的项名称应该是引用,因此:

for( auto& item : X )
{
    // E.g. assign to item here.
}

这将按顺序向由注释标记的代码提供数组中的每个项目。

C++中有两种不同的随机生成器,一种是旧的C库函数,只是一对函数,另一种是更通用和现代化但也不太容易理解的C++11。我建议您搜索并尝试一些东西。如果遇到困难,请提出新的更具体的问题。


我似乎无法弄清楚auto& item: X是什么意思,请您解释一下,并告诉我如何在我的代码中实现它,参考上面的代码片段,谢谢 :) - codelop
X 是你的数组。item 是一个任意选择的名称,用来代表该数组的一个元素(每次循环时都会得到一个不同的元素)。auto&item 的类型;你也可以写成 int&,因为你知道基本类型是 int& 表示这是一个引用。当它是一个引用时,你可以改变数组中的元素,而当它是一个副本时,改变它并不会改变原始的数组元素。 - Cheers and hth. - Alf
哦,冒号“:”只是基于范围的“for”循环语法的一部分。 - Cheers and hth. - Alf

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