2015-10-25 194 views
1

尋找關於java中隨機和密碼問題的一些幫助。首先,我試圖隨機洗牌一個數組,但我一直在混洗數組中獲得2個相同的值。隨機排列隨機數組

下面的代碼:)

public static void shuffle (char[] characterArray) { 
    Random generator = new Random(12345); 
    for (int i= 0; i<characterArray.length ; i++) {  
    int numberChoosen = generator.nextInt(characterArray.length);   
    System.out.print((characterArray[numberChoosen])); 
    } 
} 

正如你所看到的,對於{A,B,C,D}的characterArray,代碼生成改組陣列看起來像{B,C,D,D} ....爲什麼會產生兩個D的,而不是1原始數組中每個字母的字母?

謝謝! :)

+0

您也可以製作一個比較器,比較兩個隨機值生成器bij de'Random'類。然後你做'Collection.sort(array,random_comparator)'。然而'Collections.shuffle'是標準的解決方案。 – martijnn2008

+0

@ martijnn2008沒有。比較器必須一致。它不能返回隨機值。 –

+0

@JBNizet它爲什麼不能工作。您可以製作標準比較器,但不是比較兩個值,而是比較兩個新生成器的隨機值。所以,請說'我不明白你的解決方案',而不是'這是不可能的'。 – martijnn2008

回答

2

您對Random的使用不會阻止多次選擇一個條目。如果你只是簡單地隨機化數組的順序,最好建議生成一個新的數組,使用舊的數組填充它 - 一次刪除一箇舊數據項以創建新數組。

由於Java中的數組大小不可變,因此您可能需要使用一些額外的或備用的數據結構來跟蹤哪些條目已被返回。

許多可用於執行此操作的方法均可在Random shuffling of an array處獲得 - 包含完整的源代碼。

你可以嘗試這樣的事:

public static void shuffle(char[] characterArray){ 
    final List<Character> charList = new ArrayList<>(characterArray.length); 
    for(final char c : characterArray){ 
     charList.add(c); 
    } 
    Collections.shuffle(charList); 

    for(final char c : charList){ 
     System.out.print(c); 
    } 
} 

單參數Collections.shuffle通話在內部創建和使用new Random()。但是,如果必須「使用」/Show使用Random類(或使用隨機的替代源):

public static void shuffle(char[] characterArray){ 
    final Random generator = new Random(12345); 

    final List<Character> charList = new ArrayList<>(characterArray.length); 
    for(final char c : characterArray){ 
     charList.add(c); 
    } 
    Collections.shuffle(charList, generator); 

    for(final char c : charList){ 
     System.out.print(c); 
    } 
} 

現在,我不會用一個恆定值,用單參數的構造函數隨機,如果你在這裏尋找不可預測的輸出。

或者,您可以按照上述建議的方法來自己做類似的事情,而不需要撥打Collections.shuffle。回顧自己的源代碼Collections.shuffle也可能是教育。

+0

對不起,我不認爲我明白你想說什麼。 您如何在您的評論中實施您在我的代碼中標記的解決方案? – Jenna

+0

@Jenna - 請參閱我剛添加到答案的示例。 – ziesemer

+0

太棒了!但是,如果我告訴你我絕對必須使用Random類來實現它。如果我們考慮到這個約束,你的示例代碼如何改變? :) thx – Jenna

1

用於混洗數組的標準算法是Fisher-Yates shuffle,也稱爲來自Knuth的'算法P'。除非你有充分的理由不使用它,否則使用Fisher-Yates。

如果您正在查看密碼使用,那麼您將需要使用密碼安全的隨機數生成器,例如Java的SecureRandom。不要使用標準的不安全RNG,這些RNG在統計學上很好,但密碼學上非常不安全。