2012-10-12 53 views
0

我想創建一個方法來獲取名稱數組,並返回隨機重新排列名稱的列表副本。下面的代碼返回一個重複名稱的新列表。我能做些什麼來改變新列表的名字呢?給定一個String數組,如何創建第二個數組,這是對原始數據的重新排列?

public static String[] shuffle(String []names) 
{ 
    int num =0; 
    String [] newArray = new String [names.length]; 
    Random r = new Random(); 
    for(int i = 0; i<names.length; i++){ 
     num = r.nextInt(names.length); 
     if((i-1)!=num){ 
      newArray[i]=names[num]; 
     } 
    } 
    return newArray; 
} 

回答

1

像其他人建議已經有其他菜刀/簡便的方法來做到這一點,但要解決這個問題在你的代碼,你需要做的newArray名稱數組的副本(你可以可以使用Arrays.copyOf),然後正確地交換值,比如:

if(i!=num){ 
    String aux=newArray[i]; 
    newArray[i]=newArray[num]; 
    newArray[num]=aux; 
} 
+0

第(1)算法不會返回置換 - 它可能包含重複。 (2)'aux'在這一點上是沒有意義的,'newArray [i] == null',所以你基本上是在操縱原來的東西,並把'null'放在它裏面(稍後可能會流向'newArray'後來的排列)。另外,如果你想在同一個數組中進行交換,那麼這個解決方案是有偏見的,因爲必須在範圍'[0,i]中選擇隨機數來獲得均勻分佈的置換。 – amit

+0

謝謝@amid,你部分是對的。我沒有創建重複項,因爲我認爲我正在處理原始數組。我更新了我的答案。 nextInt也會生成均勻分佈的值,所以他將得到正確的置換。 – dan

+0

每個int將是均勻分佈的,但排列本身不會(有些解決方案比其他解決方案更有可能,這不是所需的特性)[This thread](http://stackoverflow.com/q/5131341/ 572670)討論了這個問題。 (我承認這是一個有點複雜的問題,但它是一個重要的問題)。此外 - 解決方案仍然不起作用 - (最後一行仍然是'names'而不是'newArray',並且您需要在開始之前填入'newArray',否則 - 它只是一堆'null's移動) – amit

1

Collections.shuffle(名單)

Info

可以使用ToList,使之成爲洗牌和一個列表,然後返回到一個數組ToArray

這可能不是最高效的,但它是最簡單的。

3

您可以使用Collections.shuffle()來洗牌清單。

如果您渴望自己動手做 - 請看fisher-yates shuffle
(僞代碼:)

for (i = n-1; i >= 0; i--) 
    swap(names,i,r.nextInt(i+1)); 

(其中swap()是一個標準的交換功能來交換數組中的兩個元素)

(請注意,如果你想與洗牌後的數組一個新的實例 - 只是複製它運行算法之前,使用Arrays.copyOf()

0
public String[] shuffle(String[] ss) { 
    List<String> list = Collections.shuffle(Arrays.asList(ss)); 
    return list.toArray(new String[ss.length]); 
} 
相關問題