我正在尝试找到一个包含1到max
位数(max
<10)的随机数。
srand((int) time(NULL));
answer = ((rand() % max) + 1);
BUT:
0,... 9只允许使用一次。
我发现等待rand()
偶然创建这样一个数字需要太长时间,所以我假设必须有一种方法来创建一个运行总计,每次添加一个数字时,比较是制成。
答案 0 :(得分:3)
如果您正在寻找一个从0到9抽取n
个数字且没有重复的整数(您的问题很难解释),那么以下就足够了。
这个想法是将所有数字从0到9放在一个帽子中然后逐个绘制出来。将每个附加到您正在构建的随机整数值。
帽子是一个最初设置为0到9的数组。
要在帽子中包含k
元素时绘制数字,请计算范围j
中的随机索引[0..k-1]
并从数组中获取该元素。然后将最后一个(k-1
)元素复制到位置j
,“删除”它。剩余的未删除数字现在位于[0..k-2],您可以重复此过程直到完成。
将数字d附加到整数值与说
相同val = 10 * val + d
将这些想法放在一起,您有以下几点。注意,这允许在第一个位置使用0,因此当打印时没有前导零时,结果实际上可能有一个少于n个数字。
unsigned random_unrepeated_digits(int n) {
int i, digits[] = { 0,1,2,3,4,5,6,7,8,9 };
unsigned val = 0;
for (i = 0; i < n; i++) {
int k = 10 - i, j = rand() % k;
val = 10 * val + digits[j];
digits[j] = digits[k - 1];
}
return val;
}
答案 1 :(得分:1)
您可以逐个生成每个数字。首先,获取从0
到9
的随机整数。例如,如果获得5
,则将其从所有数字的数组中删除:
0 1 2 3 4 6 7 8 9
接下来得到从0
到8
的随机整数,如果这次得到8
,那么第二个数字是9
。删除它并重复下一个数字。
例如,如果您需要获得8位数字,最后您只剩下4位数字,例如:
3 4 6 9
然后从0
到3
获得一个随机整数。例如,如果您获得0
,那么最后一位数字为3
,其余数字将被丢弃。
答案 2 :(得分:1)
您可以将数字{0,1,2,...,9}混洗,注意不要先放0,然后从适当的初始数字构造数字。通过这样做,在你去的时候构建结果,并在你修复了第一个ndig
数字后停止改组,你最终会得到这样的代码:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
long long rand_digits(int ndig) {
int digits[10] = {9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
long long res = 0;
for (int i = 0; i < ndig; i++) {
int r = i + rand() % (10 - i - (i == 0));
res = res * 10 + digits[r];
digits[r] = digits[i];
}
return res;
}
int main(int argc, char *argv[]) {
srand((unsigned)time(0));
for (int i = 0; i < 10; i++) {
printf("%-2d: %lld\n", i + 1, rand_digits(i + 1));
}
return 0;
}
答案 3 :(得分:0)
你可以设置一个功能:
char * randstr(int len)
{
srand(0); //seed the generator
char * str = malloc(len); //allocate exactly len bytes
int i, x; //define some loop variables
char used = 0; //used is to check if the number has already been taken
char num; //a temp value
for (i = 0; i < len; i++)
{ //this loop runs through each character in the string
used = 1;
while (used) //basically, if we already used it, find another
{
used = 0;
num = rand() % 10 + 48; //48 = '8' //returns 0-9
for (x = 0; x < i; x++)
{ //this loop checks to see if its already been used
if (str[x] == num) used = 1;
}
}
}
return str;
}
这将返回一个char数组,但不是一个空终止的数组,尽管所有数字都是ASCII形式。对于以null结尾的字符串,只需修改它,如下所示:
char * randstr(int len)
{
srand(0);
char * str = malloc(len + 1);
int i, x;
char used = 0;
char num;
for (i = 0; i < len; i++)
{
used = 1;
while (used)
{
used = 0;
num = rand() % 10 + 48; //48 = '8'
for (x = 0; x < i; x++)
{
if (str[x] == num) used = 1;
}
}
}
str[len - 1] = 0;
return str;
}
希望这有帮助。
编辑: 函数的工作方式是返回一个大小为len的字符串,只使用数字1-9,没有重复。
调用randstr(5)可以返回类似
的内容12345
93751
73485
...
请注意,如果没有更多数字可供使用,该功能将只是在那里循环。 评论在第一个函数
中获取随机数位数实际上非常简单。我们只想要一个1到10之间的随机数。完成
rand() % 10 + 1;
//so lets assign that to an int and call our function
int num = rand() % 10 + 1;
char * str = randstr(num); //assume this is the null terminated one
printf("The number was %s\n", str);
答案 4 :(得分:0)
您可以使用10位数字的数组,每次都将其随机播放并获得N个第一位数字。伪代码:
void shuffle(char[] a) {
for(int i=0; i< 10; i++) {
pos = rand() % 10;
swap(a[i], a[pos]);
}
}
int main() {
char arr[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
# it prints endlessly random numbers of random length
while (1) {
shuffle(arr);
int N = rand() % 10 + 1; # how many digits to generate
for (int i=0; i<N; i++) {
printf(arr[i]);
}
}
printf("\n");
}
这种方式可能出现的问题是当'0'出现在第一个数字时,将数字变为少于所需的数字。但你可以通过修复'shuffle'在第一个位置添加避免'0'(例如,检查第一个是'0'然后生成随机pos = rand()%9 + 1然后交换(a [0],a [如果你需要,可以获得数字。