Novice_lml 2022-03-22 22:43 采纳率: 100%
浏览 40
已结题

rand函数随机值的问题

前景:
我创建了一个二维数组,并将所有元素初始化为‘0’
在用rand函数创建随机值进行二维数组元素替换
注:以下代码不完整,为问题所在的部分代码

#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
#define EASY_count 10
#include <time.h>
#include <stdlib.h>

void Setmine(char board[ROWS][COLS], int row, int col)//我创建的一个函数 row,col 的接收值都是9
{
int count = EASY_count;
while (count)
{
int x = 1 + rand() % row;//在前面的函数内已经用srand函数利用时间戳生成rand函数的随机起点值
int y = 1 + rand() % col;//将x y 的值限制在1-9之间
if (board[x][y] == '0')
{
count--;
board[x][y] = '1';//将元素‘0’ 替换为‘1’
}
}
}

理想运行结果为将二维数组内的随机10个元素‘0’替换为‘1’
实际运行结果为 替换元素的个数是随机数,也就是说被替换的元素个数并不固定
这里的while 循环 和if判断都没有问题
只有当count的值为零的时候才会停止循环 至少循环10次
至少有10个元素被替换 但实际替换个数没有10个
想知道错误原因(或错误的可能原因)以及解决方法
万分感谢!

  • 写回答

1条回答 默认 最新

  • 赵4老师 2022-03-23 09:33
    关注

    随机必然有重复,所谓“不重复的随机”实际上是洗牌。洗牌算法参考下面:

    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    int d[6];
    int i,n,a,b,t;
    int c,j;
    void main() {
        srand(time(NULL));
        printf("shuffle 0..n-1 demo\n");
        for (n=1;n<=5;n++) {/* 测试1~5个元素 */
            printf("_____n=%d_____\n",n);
            j=1;
            for (c=1;c<=n;c++) j=j*c;/* j为n! */
            j*=n*2;
            for (c=1;c<=j;c++) {/* 测试n*2*n!次 */
                for (i=0;i<n;i++) d[i]=i;/* 填写0~n-1 */
                for (i=n;i>0;i--) {/* 打乱0~n-1 */
                    a=i-1;b=rand()%i;
                    if (a!=b) {t=d[a];d[a]=d[b];d[b]=t;}
                }
                printf("%04d:",c);
                for (i=0;i<n;i++) printf("%d",d[i]);
                printf("\n");
            }
        }
        printf("shuffle 1..n demo\n");
        for (n=1;n<=5;n++) {/* 测试1~5个元素 */
            printf("_____n=%d_____\n",n);
            j=1;
            for (c=1;c<=n;c++) j=j*c;/* j为n! */
            j*=n*2;
            for (c=1;c<=j;c++) {/* 测试n*2*n!次 */
                for (i=1;i<=n;i++) d[i]=i;/* 填写1~n */
                for (i=n;i>1;i--) {/* 打乱1~n */
                    a=i;b=rand()%i+1;
                    if (a!=b) {t=d[a];d[a]=d[b];d[b]=t;}
                }
                printf("%04d:",c);
                for (i=1;i<=n;i++) printf("%d",d[i]);
                printf("\n");
            }
        }
    }
    
    
    

    你这个问题应
    生成9进制两位数序列00~88
    将这个序列用洗牌算法打乱
    取打乱后序列的前10项,比如73,34,55,...,88
    每项拆开变成(x,y),比如(7,3),(3,4),(5,5),...,(8,8)
    然后替换你二维数组中(x+1,y+1)处的0为1

    怎么样,有没有茅塞顿开的感觉?

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录

报告相同问题?

问题事件

  • 系统已结题 3月31日
  • 已采纳回答 3月23日
  • 创建了问题 3月22日

悬赏问题

  • ¥20 西门子S7-Graph,S7-300,梯形图
  • ¥50 用易语言http 访问不了网页
  • ¥50 safari浏览器fetch提交数据后数据丢失问题
  • ¥15 matlab不知道怎么改,求解答!!
  • ¥15 永磁直线电机的电流环pi调不出来
  • ¥15 用stata实现聚类的代码
  • ¥15 请问paddlehub能支持移动端开发吗?在Android studio上该如何部署?
  • ¥20 docker里部署springboot项目,访问不到扬声器
  • ¥15 netty整合springboot之后自动重连失效
  • ¥15 悬赏!微信开发者工具报错,求帮改