//这是我的示例所显示的意思:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int i;
int a;
for (a = 0;a <10;a ++) {
i = (rand()%10)+1; // generates a number from 1-10
printf("%d\n", i);
}
//我希望循环生成一个数字,该数字给出以前没有生成的数字。例如,输出如下:
1,3,6,2,8,9,4,10,5,7
代替:
3,9,10,3,7,9,2,7,10,1
换句话说,我不想要任何副本。
答案 0 :(得分:2)
您显然不只是想要没有副本,而且您想要给定集合中的每个数字仅一次。正如罗伯特(Robert)所说,这类似于洗牌。您在C中没有“套牌”,但是您可以将其建模为数组:
int deck[] = {1,1,1,1,1,1,1,1,1,1};
这应该代表10个不同的“卡”(由它们在数组中的索引标识),每个卡都可以使用一次。现在,只需编写“绘制”卡片的代码:
int i = 0; // starting point for searching for the next card to draw
for (int n = 10; n > 0; --n) // how many cards are left
{
int skip = rand() % n; // randomly skip 0 .. n cards
while (1)
{
if (deck[i]) // card still available?
{
if (!skip) break; // none more to skip -> done
--skip; // else one less to skip
}
if (++i > 9) i = 0; // advance index, wrapping around to 0
}
deck[i] = 0; // draw the card
printf("%d\n", i+1); // and print it out
}
当然,请先播种PRNG(例如srand(time(0))
),以免每次获得的序列都不相同。
答案 1 :(得分:0)
问题中显示的想法是打印一定范围内的数字,而不要重复。通过将每个值放入数组并在其周围交换其元素,这是一种方法。
一种变化可能是您不想使用所有可能的数字,在这种情况下,只需更改PICKED
。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define ARRLEN 10
#define PICKED 10
int main(void) {
int array[ARRLEN];
srand((unsigned)time(NULL)); // seed the PRNG
for(int i = 0; i < ARRLEN; i++) { // generate the numbers
array[i] = i + 1;
}
for(int i = 0; i < ARRLEN; i++) { // shuffle the array
int index = rand() % ARRLEN;
int temp = array[i];
array[i] = array[index]; // by randomly swapping
array[index] = temp;
}
for(int i = 0; i < PICKED; i++) { // output the numbers
printf("%d ", array[i]);
}
printf("\n");
}
程序输出:
9 8 4 5 1 10 7 3 6 2
该库的PRNG并不是很随机,但是在许多情况下这并不重要。如果可以,则可以使用更好的算法。