【问题标题】:Generate random numbers without duplicates in a dynamic array C在动态数组 C 中生成不重复的随机数
【发布时间】:2023-03-28 04:38:01
【问题描述】:

我想随机化一个动态数组,每列随机数不重复,每列都是有限的,

检查我的 main.c 文件

int main()
{
        int i, j;
        int **p;

        srand(time(0));

        p = malloc(9 * sizeof *p);
        for (i=0; i<9; i++) {
                p[i] = malloc (9 * sizeof *p[i]);
        }
        if (errno) {
                perror("startup");
                exit(1);
        }

        for (j=0; j<3; j++) {
                for (i=0; i<9; i++) {
                        p[j][i] = random(j,i);
                }
        }

        for (j=0; j<3; j++) {
                for (i=0; i<9; i++) {
                        printf(" %d ", p[j][i]);
                }
                printf ("\n");
        }
} 

这是我的随机函数

int random(int *j, int *i)
{
int s = 0;
int b;
int MIN =0;
int MAX=0;
b= i;

switch (b)
{

    case 0:
            MAX = 9;
            MIN = 1;
            s = (rand() % (MAX - MIN + 1)) + MIN;

    break;

case 1:
        MAX = 19;
        MIN = 10;
        s = (rand() % (MAX - MIN + 1)) + MIN;
    break;

case 2:
        MAX = 29;
        MIN = 20;
        s = (rand() % (MAX - MIN + 1)) + MIN;
    break;

case 3:
        MAX = 39;
        MIN = 30;
        s = (rand() % (MAX - MIN + 1)) + MIN;
    break;

case 4:
        MAX = 49;
        MIN = 40;
        s = (rand() % (MAX - MIN + 1)) + MIN;
    break;

case 5:
        MAX =59;
        MIN = 50;
        s = (rand() % (MAX - MIN + 1)) + MIN;
    break;

case 6:
        MAX = 69;
        MIN = 60;
        s = (rand() % (MAX - MIN + 1)) + MIN;
    break;

case 7:
        MAX = 79;
        MIN = 70;
        s = (rand() % (MAX - MIN + 1)) + MIN;
    break;

case 8:
        MAX = 90;
        MIN = 80;
        s = (rand() % (MAX - MIN + 1)) + MIN;
    break;

}
return s;
}

所以现在我想有任何其他方式来做到这一点,但我必须使用动态分配 请给我任何可以帮助我的建议。

【问题讨论】:

  • 编译代码后得到了什么?
  • 这个int random(int *j, int *i) 应该是int random(int j, int i)
  • @hacks 这就是我得到的 prntscr.com/2auhee ,我想要没有重复的相同结果
  • 显然是的,因为在非常有限的范围内,相同的数字很可能不止一次出现。我建议您阅读 unwind 的答案或添加一个简单的检查,以确保该号码之前没有被“挑选”过。虽然它非常低效。顺便说一句,j 似乎与您的 random 函数没有任何关系。
  • @BitFiddlingCodeMonkey 不,这是不对的。当您从一组没有放回的情况下进行抽样时,概率论中不会出现重复,例如从一副牌中挑选一系列卡片。

标签: c arrays dynamic random dynamic-arrays


【解决方案1】:

我会建议一些更改:

  • 通过一次分配来分配整个矩阵,这更容易。这意味着您必须手动进行索引(即matrix[y * width + x]),但这通常不会太难。
  • 您似乎对每列中出现的数字有非常严格的要求。我建议按顺序将所有数字预先播种到矩阵中,然后随机洗牌。这通常比消除欺骗更容易。

【讨论】:

    【解决方案2】:

    为避免重复,有两种基本方法 - 1) 打乱整个集合并从前面选择一个合适的子集,或 2) 生成随机值,如果出现重复则拒绝并重试。如果您只从该范围内采样一些东西,选项 2 并不像听起来那么糟糕,但如果值的数量大于该范围的平方根,那么选项 1 很容易成为赢家。

    您可能会丢失 switch 语句。由于您的范围是i 的倍数,因此只需使用该事实来确定MAXMIN 的值:

    if (0 == i) {
      MIN = 1;
      MAX = 9;
    } else {
      MIN = 10 * b;
      MAX = MIN + 9;
    }
    s = (rand() % (MAX - MIN + 1)) + MIN;
    

    【讨论】:

      【解决方案3】:

      如果你真的需要一个不重复数字的真正随机数生成器,那根本就不是随机的 :-),

      最好的方法是根据需要创建一个列表,其中包含您需要的不重复的随机数,然后将它们按随机顺序排列。

      -- 编辑--

      如果您要生成从 1 到 99 的 X 个数字,我会执行下一个算法:

      • 生成从 1 到 99 的数字列表,并将它们放在数组 N 中。
      • 对于 i = 1 到 X,s = rand(S),从数组 N 中取数 s
      • 从数组中选择 X 个不同的数字后,您就完成了。

      你认为这对你有用吗?它简单、快速且符合您的要求。

      【讨论】:

      • prntscr.com/2auhee 检查一下,我想为宾果卡生成随机数!但在列中我不想重复
      • @Faxsy 刚刚编辑了答案,对你有用吗?
      • 我明白了你的想法,但是如何从数组 N 中取出一个随机数!
      • 在数组 N 中,数字是有序的,如果您选择一个带有 rand 的数字,一旦选择了您将其设为 0 或将其从列表中删除,则该数字将不会再次被选择并且最终X 个数字的数组将按随机顺序排列
      猜你喜欢
      • 2012-05-27
      • 2016-05-05
      • 1970-01-01
      • 2014-11-10
      • 2016-08-20
      • 2011-12-28
      • 2014-04-25
      • 2015-07-12
      相关资源
      最近更新 更多