2015-12-29 270 views
4

我学习Java的动态变化数 - 碰到这样的问题:嵌套的for循环

编写滚动骰子ň,其中骰子都是d片面的程序。通过 使用模拟,使用骰子报告概率为 的总概率x或更大的概率值,其中x,n和d全部作为输入给出 。例如,如果n = 2,d = 6和x = 7,则程序 应报告58.3%的概率(大约)。

这是我想出了

public class Main { 

    public double calcProbability(int n, int d, int x){ 
     int[] sums = new int[(int)Math.pow(d, n)]; //Creates an array of max size needed 
     int counter = 0;  
     int occurrences = 0; //No. of times that the number being added to the array is greater than d 
     for(int i=1;i<=d;i++){ 
      for(int j=1;j<=d;j++){ 
       if((i+j)>=x){ 
        occurrences++; 
       } 
       sums[counter]=(i+j); 
       counter++; 
      } 
     } 
     return (double)occurrences/Math.pow(d, n); //Returning probability 
    } 

    public static void main(String[] args) { 
     System.out.println(new Main().calcProbability(2, 6, 7)); 
    } 

} 

它工作正常的N = 2(我认为),因为我使用两个嵌套的for循环。但是我无法弄清楚如何用n来改变for循环的数量(这将允许我将所有可能的总和添加到数组中 - 其余代码应该按原样工作)。

希望能得到一些指导。


谢谢大家,考虑到每个人的贡献后,这里的修订方法:

public double calcProbability(int n, int d, int x){ 
     Random random = new Random(); //Random numbers simulate dice rolling 
     int occurrences = 0; //No. of times that the number is greater than d 
     for(int i=0;i<100000;i++) 
     { 
      int sum = 0; 
      for(int j=0;j<n;j++) 
      { 
       sum+=random.nextInt(d)+1; 
      } 
      if(sum>=x) { 
       occurrences++; 
      } 

     } 
      return (double)occurrences/100000; //Will be an approximation 
    } 

这是毫无意义的保存这些数字,然后计算发生的次数 - 而仅计算发生时,它需要放置并继续前进。

+0

您可以在没有模拟的情况下计算确切的更改。 –

+0

添加到@PeterLawrey:你**不能**用模拟计算概率。你必须拿出一个公式,并解决给定输入的公式 – luk2302

+1

即使对于给定的输入,我也不确定这是否会回答问题。你不是“滚动骰子”,因为我知道你应该使用随机数字发生器。这个想法不是要计算概率值(可以用手来完成),而是模拟掷骰子并验证它是否收敛到某个值。 –

回答

1

谢谢大家,考虑到每个人的贡献后,这里的修订方法:

public double calcProbability(int n, int d, int x){ 
     Random random = new Random(); //Random numbers simulate dice rolling 
     int occurrences = 0; //No. of times that the number is greater than d 
     for(int i=0;i<100000;i++) 
     { 
      int sum = 0; 
      for(int j=0;j<n;j++) 
      { 
       sum+=random.nextInt(d)+1; 
      } 
      if(sum>=x) { 
       occurrences++; 
      } 

     } 
      return (double)occurrences/100000; //Will be an approximation 
    } 

这是毫无意义的保存这些数字,然后计算发生的次数 - 而仅计算发生,当它发生和移动on

4

出于动态循环的目的,答案如下。不过,请跳至第二段,以获取更多推荐的方法。获得动态循环的方式是递归。如果你愿意,我可以详细说明,但是在高层次上,你拥有的是一个指定第n个骰子和减量的参数,当它到达第0个骰子时,递归结束。您必须对变量进行相当多的修改,然后将它们移动到参数或全局变量中,以便您可以继续使用该函数进行更新。

在这个问题的情况下,我会以不同的方式处理它。创建一个名为Roll的函数,它需要两个参数:骰子值的范围和掷骰子的数量。我将留给你的功能的细节,但它涉及随机生成一定数量的数字。由于问题需要模拟,所以将这个Roll函数调用很多次,然后使用数组来跟踪出现的答案。在这一点上,做分工和百分比来得到一个好的近似值。

+1

为什么使用递归解决这个问题?这里不需要“动态循环数”... –

+1

我更多地指的是循环的动态数量,而不是这里的问题 – Untitled123

+1

我同意@ Jean-BaptisteYunès这实际上并没有回答这个问题。关于循环与递归你绝对正确,但是这个问题不能通过实际上滚动的骰子来解决--OP必须做它背后的数学。 – luk2302

1

也许你应该在一个循环中迭代骰子滚动的可能结果。

结果是一个大小为n的整数数组,其值全为[1,d]

您的代码将是:

int occurrences = 0; 
int count = 0; 
Result result = new Result(n, 1); // n times 1. 
while(result != null) 
{ 
    if (result.Sum >= x) occurrences++; 
    count++; 

    GetNextResult(result); 
} 

double probability = occurrences/(double) count; 

GetNextResult返回下一个可能的结果,或者null如果输入为[d, d, ..., d]

当然,你必须正确地编码Result类。