2016-11-18 100 views
1

我在按照隨機順序打印出來時遇到了一些麻煩。我插入的8個單詞將需要以隨機順序打印出來。現在我只能以隨機順序生成其中的一些,因爲如果生成兩次相同的數字,它將覆蓋之前的空間。我怎樣才能消除這個問題?以隨機順序輸入字符串並將它們打印

#include <stdio.h> 
    #include <stdlib.h> 
    #include <time.h> 
    #include <string.h> 
    #include <ctype.h> 
    #define MAX 50 

    int readLine(char string[]); 

    int main(void) 
    { 
     int i; 
     char str[8][MAX], temp[8][MAX]; 
     srand((unsigned)time(NULL)); 
     int r_num; 

     printf("Enter 8 words:\n"); 

     for(i=0; i<8; ++i) 
     { 
      readLine(str[i]); 
     } 


     for (int i = 0; i < 8; i++) 
     { 
      r_num = rand()%8+1; 
      strcpy(temp[r_num], str[i]); 
     } 

    printf("\nRandom order of words: \n"); 
    for(i=0; i<8; ++i) 
    { 
     printf("%s\n", temp[i]); 
    } 
    printf("\n"); 

    return 0; 
} 

int readLine(char string[]) 
{ 
    int ch; 
    int i=0; 
    while (isspace(ch = getchar())) 
     ; 
    while (ch != '\n' && ch != EOF) 
    { 
     if (i < MAX) 
     { 
      string[i++] = ch; 
      ch = getchar(); 
     } 
    } 
    string[i] = '\0'; 
    return i; 
} 

回答

1

洗牌數據的方法之一是從尚未選擇的內容中選取。

int main(void) 
{ 
    int i; 
    char str[8][MAX]; 
    int order[8]; /* order list */ 
    srand((unsigned)time(NULL)); 
    int r_num; 

    printf("Enter 8 words:\n"); 

    for(i=0; i<8; ++i) 
    { 
     readLine(str[i]); 
    } 

    /* initialize order list */ 
    for (i = 0; i < 8; i++) 
    { 
     order[i] = i; 
    } 
    for (i = 7; i > 0; i--) /* select from back to front */ 
    { 
     int pos = rand() % (i + 1); /* pick one position randomly */ 
     /* pick selected element by swapping */ 
     int temp = order[pos]; 
     order[pos] = order[i]; 
     order[i] = temp; 
    } 

    printf("\nRandom order of words: \n"); 
    for(i=0; i<8; ++i) 
    { 
     printf("%s\n", str[order[i]]); /* print strings in the shuffled order */ 
    } 
    printf("\n"); 

    return 0; 
} 
+0

的感謝!這對我來說很簡單。我沒有得到的是,當你生成一個隨機數時,它會從第一次選擇一個範圍,即從0到8。第二次0到7 ..至少這是我假設它做的。那麼爲什麼它不會兩次選擇相同的數字呢?即第一次5,然後第二次5? – xxFlashxx

+0

@Alex第一次選擇5時,通過交換將5移動到陣列的後部。所以候選者第二次是[0,1,2,3,4,7,6],而* index * 5可以再次選擇,* data * 5將不會被再次選擇。 'i'從7開始(元素個數 - 1),所以第一次迭代的範圍是0到7(非負數模(7 + 1)),而不是0到8。第二次是0到6。從一個候選人中選擇是顯而易見的,所以可以使用'i> 0'來代替'i> = 0'。 – MikeCAT

0

之前存儲輸入線string[i]隨機輸出線temp[r_num],你剛纔覈實,如果所選擇的輸出是免費的。

第一步,從第一 環路初始化輸出數組temp[8][MAX]

for(i=0; i<8; ++i) 
{ 
    strcpy(temp[i],""); // set each output line to free (empty). 
    readLine(str[i]); 
} 

第二步驟中,在隨機化選擇器環而選定串 不輸出: 的隨機指數應爲0至7.

for (i = 0; i < 8; i++) 
{ 
    do { 
     r_num = rand()%8; // index is between 0 and 7 
    } while (strlen(temp[r_num])!=0); // output shall be free/empty 
    strcpy(temp[r_num], str[i]); 
} 

相反的:

for (int i = 0; i < 8; i++) 
    { 
     r_num = rand()%8+1; // error index start from 0 
     strcpy(temp[r_num], str[i]); 
    } 
1

你需要照顧,你不應該相同的數據複製到臨時數組。

您可以檢查以下簡單的邏輯,

1)求randno r_num

2)交換。海峽[r_num]和STR [MAXLEN]

3)遞減最多1

4 LEN)重複

for (i = 0; i < 8; i++) 
{ 
    // Commenting your code 
    //r_num = rand()%8+1; 
    //strcpy(temp[r_num], str[i]); 

    memset(temp1,0,sizeof(temp1)); 
    r_num = (rand()%(8-i))+1; 
    if(r_num != i) // Do not swap if r_num is max 
    { 
     //swapping 
     strcpy(temp1,str[r_num]); 
     strcpy(str[r_num],str[7-i]); 
     strcpy(str[7-i],temp1); 
    } 
} 

我希望這將幫助你:)

相關問題