【问题标题】:Asterisk Histogram for random dice rolls of 3 dice3 个骰子随机掷骰的星号直方图
【发布时间】:2013-10-30 00:24:52
【问题描述】:
#include <stdio.h> 
#include <stdlib.h>
#include <time.h>
#include <string.h>

int main()
{
int i;
int d1, d2, d3;
int a[16];
    srand(time(NULL));

for(i = 0; i <= 15; i++)   
    a[i] = 0;   
for(i = 0; i < 1000; i = i + 1)   
{   
    d1 = rand() % 6 + 1;   
    d2 = rand() % 6 + 1; 
    d3 = rand() % 6 + 1;  
    ++a[d1 + d2 + d3 - 3];   
}  
char asterisks[0x400];
memset(asterisks, '*', sizeof(asterisks)); 
for(i = 0; i <= 15; i = i + 1) 
{   
    printf("%3d - ", i+3);   

    for(j=0;j<a[i];j++)
    {
    printf("%c ",'*');   

    }
    printf("\n");  
}

return 0;
}    

更新代码。
目标是有一个星号直方图来判断掷出 1000 次 3 个骰子的骰子。就是计算 3 到 18 之间的和有多少个组合。 直方图输出应如下所示:

Frequency of Results for 3d6
  3 - *
  4 - **
  5 - ****
  6 - *******
  7 - *********
  8 - ***********
  9 - ************
 10 - ************
 11 - *************
 12 - **********
 13 - *************
 14 - ********
 15 - ******
 16 - ***
 17 - ***
 18 - **

这是我现在的输出:

3 - * * 
4 - * * * * * * * * * * * * * * * * * * * * 
5 - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
6 - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** * * 
7 - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** * * * * * * * * * *     * * * * * * * * * * * * 
8 - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** * * * * * * * * * * * * * * * * * * * * * * * * * 
9 - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
10 - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
11 - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** * * * * * * * * * 
12 - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
13 - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** * * * * 
14 - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** * * * * * * * * * * * * * * * * * * * * * * * * * 
15 - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** * * * * * * * 
16 - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
17 - * * * * * * * * * 
18 - * * * * * * * * 

【问题讨论】:

  • 还有什么问题?
  • 如果 a 被定义为 13 个条目的数组,你如何访问到 a[18]?而且我只数了2个骰子..
  • @Leeor: stack-overflow...buffer-overflow...发布的代码似乎与站点名称非常匹配:p
  • @EliasVanOotegem 抱歉,我正在努力学习……
  • @user2306249:不用担心...我已经尝试回答您的问题,指出您应该解决的一些问题,希望对您有所帮助

标签: c random histogram dice


【解决方案1】:

用星号填充字符数组的方法可以通过多种方式完成,其中一些已经解释过here,这是几个小时前发布的问题...

在另一件事上:
您正在调用 rand 函数,但没有提供种子...rand 默认情况下会表现得好像它作为种子传递了 1,并且您编译的程序将产生 not-如此随机的结果。
考虑添加这个:

#include <stdlib.h>
#include <time.h>

int main()
{
    int i;
int d1, d2;
int a[13];
    srand(time(NULL));//seed current time
}

正如 Jongware 指出的那样:

d1 = rand() % 6 + 1;
d2 = rand() %6 + 1;

只是没有意义:

d1 = rand() % 18 + 1;

做同样的事情,只需要 1 个函数调用。但是,您对这个 int 值所做的操作还有另一个问题:

您还使用了一个整数数组 (a[13]),其声明意味着您可以使用的最高偏移量是 12,最低(一如既往)是 0。然而,您的循环从偏移量 3 开始,一直到 18...
我知道这个站点被称为 stackoverflow,但您的代码似乎正在积极地朝着Buffer overflow 工作。请解决这个问题...

【讨论】:

  • 一个不太明显的优化:调用rand一次,范围为3..18。
  • @Jongware:你是对的(我已将其添加到我的答案中,归功于你),但 OP 有更大的鱼要炒 IMO ......至少不是:溢出问题
  • 嗯,我的建议是从 3 开始——你至少可以抛出三个 :-) (正如 elsethread 所评论的,范围为“0..15”工作原理完全相同。)
【解决方案2】:

3-18你需要16个大小的数组

int a[16]; 

a[0] indicates Number of 3 counts and 
a[1] indicates Number of 4 counts and 
....

a[15] indicates Number of 18 counts.

你需要改变这个for循环

 for(i = 0; i <= 15; i++)   
  a[i] = 0;   

还有这句话

   a[d1 + d2+d3] = a[d1 + d2 + d3] + 1;

这样修改

     ++a[d1 + d2 + d3 - 3];

最后的 for 循环也需要两个循环。

for(i = 0; i <= 15; i = i + 1) 
   {   
    printf("%3d - ", i+3);   

    for(j=0;j<a[i];j++)
       {
        printf("%c ",'*');   

       }
        printf("\n");  
   }

【讨论】:

  • j 是从哪里来的?
  • @user2306249 你需要声明额外的变量。
【解决方案3】:

您可以使用memset 用星号填充缓冲区,使用"%*s" printf 格式打印任意数量的内容:

char asterisks[0x400];
memset(asterisks, '*', sizeof(asterisks));

for(i = 3; i <= 18; i = i + 1)   
{   
    printf("%d - %*s\n", i, a[i], asterisks);  
}

是的,正如 cmets 中提到的,您应该定义足够长的 a:

int a[19];

【讨论】:

    猜你喜欢
    • 2015-04-30
    • 1970-01-01
    • 2021-08-19
    • 1970-01-01
    • 2014-10-07
    • 2015-05-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多