簡體   English   中英

對作為參數傳遞的數組進行混洗的函數

[英]A function that shuffles an array passed as an argument

我正在學校做一個項目,我想創建一個函數來對作為參數傳遞的數組進行混洗。 我試圖創建一個,但它沒有按我預期的那樣工作......

在這段代碼中,我試圖復制傳遞數組的元素並在第二個數組中以隨機順序設置它們。 然后,在傳遞的數組中再次復制它們..

這是源代碼:

void shufarray(int* array, int b)
{
    int hold[b];  
    int i,k;  
    int randV=0, randHold=0;
    srand(b);  
    for(i=0; i<b; ++i) {      
        hold[rand() % (b-1)] = array[i]; 
        k=0;
        do { 
            if(k==0) { 
                randHold = randV;
                k=-1;
            } //end if
            randV = rand()%(b-1);         
        } while(randHold != randV);//end of do\while stetment 
        hold[randV] = array[i];     
    } //end for  
    for(i=0;i<b;++i) {
        array[i]=hold[i]; 
    } //end for 
} //end shufarray()

這是輸出:

hold[ 0 ] = 8
hold[ 1 ] = 11
hold[ 2 ] = 2
hold[ 3 ] = 15
hold[ 4 ] = 18
hold[ 5 ] = 10
hold[ 6 ] = 11
hold[ 7 ] = 17
hold[ 8 ] = 24
hold[ 9 ] = 21
hold[ 10 ] = 12
hold[ 11 ] = 2
hold[ 12 ] = 15
hold[ 13 ] = 9
hold[ 14 ] = 13
hold[ 15 ] = 1
hold[ 16 ] = 15
hold[ 17 ] = 1
hold[ 18 ] = 22
hold[ 19 ] = 11
hold[ 20 ] = 11
hold[ 21 ] = 18
hold[ 22 ] = 17
hold[ 23 ] = 4
hold[ 24 ] = 7
shuffled_hold[ 0 ] = 7
shuffled_hold[ 1 ] = 32561
shuffled_hold[ 2 ] = 22
shuffled_hold[ 3 ] = 0
shuffled_hold[ 4 ] = 18
shuffled_hold[ 5 ] = 8
shuffled_hold[ 6 ] = -632114865
shuffled_hold[ 7 ] = 32561
shuffled_hold[ 8 ] = -628693440
shuffled_hold[ 9 ] = 11
shuffled_hold[ 10 ] = 15
shuffled_hold[ 11 ] = 18
shuffled_hold[ 12 ] = 1
shuffled_hold[ 13 ] = 13
shuffled_hold[ 14 ] = 15
shuffled_hold[ 15 ] = 12
shuffled_hold[ 16 ] = 17
shuffled_hold[ 17 ] = 0
shuffled_hold[ 18 ] = 4
shuffled_hold[ 19 ] = 17
shuffled_hold[ 20 ] = 7
shuffled_hold[ 21 ] = 0
shuffled_hold[ 22 ] = -1
shuffled_hold[ 23 ] = 0
shuffled_hold[ 24 ] = 0

所以我試圖了解這個操作的原理,任何人都可以幫我找出問題所在..謝謝。

問題

在前面的代碼中,我認為解決方案是創建一個數組hold[]來保存從array[]隨機復制的元素。 比將元素從hold[]再次復制回array[]問題是:

  • hold[]未初始化

  • 有時程序會覆蓋已經覆蓋的元素

  • srand(b) 將始終根據長度給出相同的排列

解決方案

我根據評論中建議的參考修改了代碼。

正確的做法是從最后一個元素array[n-1] ,將它與從整個數組(包括最后一個)中隨機選擇的元素交換。 現在考慮from 0 to n-2的數組(大小減 1),並重復該過程直到我們命中第一個元素。 詳細算法如下:

  for i from n - 1 downto 1 do
       j = random integer with 0 <= j <= i
       exchange a[j] and a[i] .

編碼

void shufarray(int* array, int b){
    int i,k=0;
    srand(time(NULL));//set the seed
    /* Starting from the last element and swap one by one.
     * NOTE: i > 0 it's because there's no need to run for the first element */
    for (i = b-1; i > 0; i--){
        int j = rand() % (i+1);
        //swap
        k =  array[i];
        array[i] = array[j];
        array[j] = k;
    }//end for
}//end shufarray()

輸出

hold[ 0 ] = 8
hold[ 1 ] = 11
hold[ 2 ] = 2
hold[ 3 ] = 15
hold[ 4 ] = 18
hold[ 5 ] = 10
hold[ 6 ] = 11
hold[ 7 ] = 17
hold[ 8 ] = 24
hold[ 9 ] = 21
hold[ 10 ] = 12
hold[ 11 ] = 2
hold[ 12 ] = 15
hold[ 13 ] = 9
hold[ 14 ] = 13
hold[ 15 ] = 1
hold[ 16 ] = 15
hold[ 17 ] = 1
hold[ 18 ] = 22
hold[ 19 ] = 11
hold[ 20 ] = 11
hold[ 21 ] = 18
hold[ 22 ] = 17
hold[ 23 ] = 4
hold[ 24 ] = 7
shuffled_hold[ 0 ] = 24
shuffled_hold[ 1 ] = 9
shuffled_hold[ 2 ] = 8
shuffled_hold[ 3 ] = 1
shuffled_hold[ 4 ] = 15
shuffled_hold[ 5 ] = 11
shuffled_hold[ 6 ] = 11
shuffled_hold[ 7 ] = 21
shuffled_hold[ 8 ] = 17
shuffled_hold[ 9 ] = 7
shuffled_hold[ 10 ] = 11
shuffled_hold[ 11 ] = 11
shuffled_hold[ 12 ] = 18
shuffled_hold[ 13 ] = 10
shuffled_hold[ 14 ] = 1
shuffled_hold[ 15 ] = 15
shuffled_hold[ 16 ] = 13
shuffled_hold[ 17 ] = 2
shuffled_hold[ 18 ] = 18
shuffled_hold[ 19 ] = 4
shuffled_hold[ 20 ] = 17
shuffled_hold[ 21 ] = 2
shuffled_hold[ 22 ] = 12
shuffled_hold[ 23 ] = 15
shuffled_hold[ 24 ] = 22

參考資料: Fisher-Yates shuffle

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM