2011-11-07 36 views
0

使用C,我如何隨機顯示數組中的值,因爲這些值中的每一個都有唯一對應的值,而不重複顯示任何這些值? 使用C,我的目標是隨機顯示一個問題,一次一個,設置一定量的迭代。我創建了一個包含問題及其四個可能答案的數組。我還創建了一個數組,爲每個問題提供正確的答案。考慮到每個值都具有唯一的對應值,我該如何在數組中隨機顯示值?

非常感謝你們......你們已經非常有幫助

#include <stdio.h> 
#include <conio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <ctype.h> 
#include <time.h> 

int random(); 
int l, qs[10]; 
int main() 
{ 
for (l=0;l<10;++l) 
qs[l]=0; 
srand(time(NULL)); 
char questions [] [50] ={"aa \n\na)\n\nb)\n\nc)\n\nd)",\"bb \n\na)\n\nb)\n\nc)\n\nd)", "cc \n\na)\n\nb)\n\nc)\n\nd)", \ 
"dd \n\na)\n\nb)\n\nc)\n\nd)", "ee \n\na)\n\nb)\n\nc)\n\nd)", \ 
"ff \n\na)\n\nb)\n\nc)\n\nd)", "gg \n\na)\n\nb)\n\nc)\n\nd)", \ 
"hh \n\na)\n\nb)\n\nc)\n\nd)", "ii \n\na)\n\nb)\n\nc)\n\nd)", \ 
"jj \n\na)\n\nb)\n\nc)\n\nd)"}; 
char answers [10] = {'a','b', 'b','d','c','b','d','b' ,'c', 'b'}; 
int i, j; 
char ans; 
int score = 0; 
printf ("Read each question carefully and choose your best answer."); 
for (i=1;i<6;i++) 
{ 
j = random(); 
fflush(stdin); 
clrscr(); 
printf ("\n %d %s \n\n", i, questions [j]); 
printf ("\n Enter Answer: "); 
do 
{ 
ans = tolower(getchar()); 
}while ((ans < 'a') || (ans > 'd')); 
printf ("\nYou chose: %c ", ans); 
if (ans == answers[j]) 
{score = score + 1; 
printf ("\n\nCorrect. %d Mark/s", score); 
}else{printf ("\n\nIncorrect. 0 Mark/s");} 
printf("\n\nPress Enter for next question..."); 
getch(); 
} 
getch(); 
return 0; 
} 
random() 
{ 
int k; 
do 
{k=rand()%10; 
}while (qs[k]!=0); 
qs[k]= 1; 
return k; 
} 
+0

好的無限'while'循環如果其中一個條件沒有通過。 – AusCBloke

回答

0

你需要另一個列表來跟蹤你提取什麼項目。

一個可能的解決方案:混洗輸入數組。見http://benpfaff.org/writings/clc/shuffle.html

如果您不能修改輸入數組,可以用指數來代替,間接的水平。 這是另一種可能的解決方案。

1)創建一個大小爲n的整數數組。

2)使用從0到n-1(包含)的值填充數組。

3)你洗牌陣列(尋找一個混洗方法來隨機化的陣列),例如,再次http://benpfaff.org/writings/clc/shuffle.html

4)然後,在陣列上進行迭代從0到n-1(含),每數組中的項目將成爲源數組中的索引。

完成。

另一種可能的解決方案是使用鏈表。

1)以隨機順序填充鏈表(這很容易)。

僞代碼,例如

for (int i = 0; i < n; ++i) 
{ 
    if (rand() & 1) 
     insert_at_the_beginning(); 
    else 
     insert_at_the_end(); 
} 

2)當你需要一個新的項目,你從鏈表彈出的第一個項目。

完成。

您也可以將布爾值的數組,但在這種情況下,算法的複雜度會更高,第一種方法似乎不夠。

0

不要在for循環中調用srand。在程序開始時調用一次,並讓它成爲。做你想做的事情的酷酷方式是費希爾 - 耶茨洗牌。如果你想使用它,你可以查看它。如果不是,這裏是平凡解:

1)循環之前,大小爲10的布爾變量數組(虐待稱之爲usedArray)和所有設置爲false。

2),以獲得問題索引,得到0和9之間的隨機數,包括端值(J =蘭特%10;是好的),使得usedArray [j]爲假;然後,將usedArray [j]設置爲true。您可能需要使用一段時間或做一段時間的循環。現在

2)你的問題是問題[J],它的相應的答案是答案[J]

3)根據需要重複

1

首先,我會改變你如何安排數據。現在,您有三個平行陣列,一個用於提問,一個用於潛在答案,另一個用於正確答案。

取而代之的是,我想創建一個結構來存儲所有的數據一個問題,這樣的事情:

struct qa { 
    char question[64]; 
    char answers[4][32]; 
    int correct_answer; 
}; 

然後我會創建質量檢查結構的數組,每個保存所有數據爲單個問題和答案:

qa questions[] = { 
    { "what color is the sky?", { "red", "green", "blue", "yellow"}, 2}, 
    { "When is Christmas?", {"January", "July", "September", "December"}, 3}, 
    // ... 
}; 

從那裏,你有幾個選擇。如果您打算提出所有(或幾乎)所有問題,並且主要想要對訂單進行洗牌,您可以使用Fisher-Yates洗牌作爲@Salvatore Previti建議。

如果您在任何特定時間只詢問一小部分問題,那可能非常浪費。在這種情況下,您可以使用(作爲一個例子)由Robert Floyd發明的選擇算法,我在previous answer中討論過。

相關問題