【问题标题】:Need to generate 4 random numbers without repetition in C programming. 1 to 4在 C 编程中需要生成 4 个不重复的随机数。 1到4
【发布时间】:2019-12-17 00:11:21
【问题描述】:

我想使用 C 编程以随机方式生成数字 1 到 4。 我已经准备好在while 循环中直接打印a[0],对于任何其他元素,程序会检查从a[1]a[3] 的新数字是否与之前的任何元素相同。已经为此创建了一个函数。 int checkarray(int *x, int y)

该函数通过减少传递的地址来一一检查当前元素和之前的元素。如果它与值匹配,则通过将值零分配给条件变量 (int apply) 来退出循环。

return apply;

main 程序中,如果check==1 匹配int check,则打印数字,否则重复循环。

面临的问题:生成的随机数在 2 到 4 之间变化。 例如

2 4 2 4 3 1 3 3 4

有时也会重复。

#include <stdio.h>
#include <conio.h>

int checkarray(int *x, int y);

void main() {
    int a[4], i = 0, check;

    srand(time(0));

    while (i < 4) {
        a[i] = rand() % 4 + 1;
        if (i == 0) {
            printf("%d ", a[i]);
            i++;
            continue;
        } else {
            check = checkarray(&a[i], i);
        }
        if (check == 1) {
            printf("\n%d ", a[i]);
        } else {
            continue;
        }
        i++;                    
    }

    getch();
}

int checkarray(int *x, int y) {
    int arrcnt = y, apply = 1, r = 1;
    while (arrcnt > 0) {
        if (*x == *(x - 2 * r)) {
            apply = 0;
            exit(0);
        } else {
            arrcnt--;
            r++;
            continue;
        }
    }   
    return apply;
}

【问题讨论】:

  • 您的 checkarray 函数在到达 exit(0) 时会正常结束程序。我不确定那是你想要的。
  • 你有什么问题?
  • 有一种更简单的方法可以做到这一点。将四个数字放在一个数组中,随机交换,然后依次使用。
  • 你想要的是一个带有该数组的 Fisher Yates 洗牌
  • 嘿,感谢您在描述中付出了巨大的努力。但我不明白你的问题是什么。您能否描述一下您遇到的问题,而不仅仅是您想要完成的任务?也许您也可以使用tour 并阅读minimal reproducible example

标签: c function random repeat


【解决方案1】:

让我们看看checkarray 函数,它应该检查数组中是否已经存在一个数字。

这样称呼:

check = checkarray(&a[i], i);

其中a 是一个由 4 个整数组成的数组,i 是实际索引,因此它会尝试向后扫描数组以查找是否出现 a[i]

int checkarray(int *x,int y)
{
    int arrcnt=y,apply=1,r=1;
    while(arrcnt>0)
    {
        if(*x==*(x-2*r))
        //         ^^^    Why? This will cause an out of bounds access.
        {
            apply = 0;
            exit(0);    // <-- This ends the program. It should be a 'break;'
        }
        else
        {
            arrcnt--;
            r++;
            continue;
        }
    }   
    return apply;
}

在不改变界面的情况下(在我看来这很容易出错),它可以被重写为

int check_array(int *x, int y)
{
    while ( y )
    {
        if ( *x == *(x - y) )   
            return 0;
        --y;
    }
    return 1;
}

可测试here

不过,还有许多其他问题需要解决,所以请也看看这些问答。

Does "n * (rand() / RAND_MAX)" make a skewed random number distribution?
Why do people say there is modulo bias when using a random number generator?
Fisher Yates shuffling algorithm in C
int main() vs void main() in C
Why can't I find <conio.h> on Linux?

【讨论】:

    【解决方案2】:

    您的方法很乏味,但可以使用:

    • 不需要对第一个数字进行特殊处理,只需让checkarray() 为空数组返回未找到。
    • 您应该向checkarray() 传递不同的参数:指向数组的指针、要检查的条目数和要搜索的值。
    • 你不应该使用exit(0)checkarray()返回0:它会导致程序立即终止。

    这是修改后的版本:

    #include <stdio.h>
    #include <conio.h>
    
    int checkarray(int *array, int len, int value) {
        int i;
        for (i = 0; i < len; i++) {
            if (array[i] == value)
                return 0;
        }
        return 1;
    }
    
    int main() {
        int a[4], i = 0, value;
    
        srand(time(0));
    
        while (i < 4) {
            value = rand() % 4 + 1;
            if (checkarray(a, i, value)) {
                printf("%d ", value);
                a[i++] = value;
            }
        }
        printf("\n");
        getch();
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 2010-11-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-11
      • 1970-01-01
      • 2012-09-25
      • 2011-08-19
      • 2021-10-23
      相关资源
      最近更新 更多