2015-12-29 317 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類。