2017-02-23 105 views
0

我正試圖編寫一個函數,根據它的頻率計數來選擇一個字母。隨機字母選擇函數

這裏,字母a到z具有下列頻率:

4778 ,1145 ,1994 ,2075 ,5940 ,762 ,1403 ,1446 ,4263 ,111 ,745 ,3231 ,1625 ,3467 ,3543 ,1455 ,94 ,3678 ,3775 ,3092 ,1883 ,529 ,649 ,139 ,902 ,180 

,其基於它們的加權概率隨機信功能:

public Letter chooseOnWeight(List<Letter> letterNew) { 

    int completeWeight = 0; 
    int completeWeightUpdated = 0; 
    List<Integer> updatedWeightList = new ArrayList<>(); 
    for (Letter letter : letterNew) { 
     updatedWeightList = letter.getWeight(); 
     for (int i = 0; i < updatedWeightList.size(); i++) { 
      completeWeight += updatedWeightList.get(i); 

     } 
     completeWeightUpdated += completeWeight; 
    } 

    int countWeightUpdated = 0; 
    List<Integer> updatedCountList = new ArrayList<>(); 
    double r = Math.random() * completeWeight; 
    double countWeight = 0.0; 
    for (Letter letter : letterNew) { 
     updatedCountList = letter.getWeight(); 
     for (int i = 0; i < updatedWeightList.size(); i++) { 
      countWeight += updatedCountList.get(i); 
     } 
     countWeightUpdated += countWeight; 

     if (countWeightUpdated >= r) { 
      return letter; 
     } 
    } 
    throw new RuntimeException("Should never be shown."); 
} 

信件類,其中包含getWeight ()函數:

public class Letter { 
    char name; 
    List<Integer> weight; 

    public Letter(char name){ 
     this.name = name; 
    } 

    public char getName() { 
     return name; 
    } 

    public List<Integer> getWeight() { 
     return weight; 
    } 

    public void setWeight(List<Integer> weight) { 
     this.weight = weight; 
    } 


} 

不幸的是,字母是生成的只是a-f。出於某種原因,它不會在f後生成任何字母。

+0

也許向我們展示您的getWeight方法 –

+0

現在將添加getWeight() – statsguyz

+0

創建一個TreeMap <整數,字符>,其中密鑰是該字母的累計權重(4778爲A,4778 + 1145爲B,4778 + C + 1145 + 1994等),其值爲字母。在這個列表上需要一次通過。生成一個介於0和Z的累計權重之間的隨機數,然後調用map.ceilingEntry()來查找與此隨機數對應的字母。 –

回答

1

重置countWeight0在第二個主循環的每次迭代之後,其中您遍歷letterNew中的每個Letter。因爲通過不重置countWeightcountWeightUpdated的預期值將在內部for循環之後受影響,其中將按updatedCountList中的字長增加。在此內循環之後,countWeightUpdated應該只會遞增當前迭代的當前Letter的總權重值,而不是迄今爲止所有實例Letter的總權重。例如,如果a的總重量爲1000,b的總重量爲1100,c的總重量爲1200,則在迭代完成後,您希望countWeightUpdated的值僅爲1000 + 1100 + 1200 = 3300 ,b和c。但是,您的循環會執行以下添加,而不是1000 + 2100 + 3300 = 8400,因爲每次迭代後countWeight將是之前查看的所有字母的總重量,而不是每個字母的重量。 2100來自(1000 + 1100),3300來自(1000 + 1100 + 1200)。因此,這將限制返回到較短範圍的字母範圍。解決方法是簡單的,

for (Letter letter : letterNew) { 
    updatedCountList = letter.getWeight(); 
    for (int i = 0; i < updatedWeightList.size(); i++) { 
     countWeight += updatedCountList.get(i); 
    } 
    countWeightUpdated += countWeight; 
    countWeight = 0; //THIS IS THE FIX 
    if (countWeightUpdated >= r) { 
     return letter; 
    } 
} 

而且,你在你的第一主有類似的問題與completeWeightUpdated循環,但它不是在方法中使用的很多,所以我並沒有提到它,因爲它似乎是多餘的。