✔ 最佳答案
To提問者:
你這個程式對輸入資料檢驗不嚴謹,比如就漏了檢驗第一組和第二組是否重複。對非數字字元的輸入也沒處理,輸入過程有時會不可收拾。
另外挑選過程也有問題。
若在原架構上勉強修正,俺直覺將會凌亂不堪。
打掉重建,以全新架構呈現!
若你能接受這項建議,俺應可改寫個範例給你參考。
2009-04-05 18:20:28 補充:
有人欲效「XD寶典」而「砍」掉重「練」,俺樂觀其成。
言歸正傳,切誤把「打掉重建」誤解成「砍題重問」。
2009-04-05 20:01:45 補充:
說起「刖」那個字,害我趕忙到MSN找高手開釋,(手邊沒字典),
聞釋後,心中一懍,一股寒意直串腦門,
在呌嗦間,CC二脈真氣亂竄,隱痛多日的「樂透穴」頓然開通,
樂透選號密功乃順勢架構,水到渠成。
稍待片刻,測試後自當問世。
2009-04-05 20:55:29 補充:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAX 48
int check(int a[], int b[]);
int main(int argc, char* argv[])
{
int a[6] , b[6] ,rand_a[10][6] , box[MAX];
int i ,j ,m ,tmp;
//非數字字元的輸入,即時要求重新輸入
//不合規定的輸入,要求重新輸入
do
{
do {
printf("\n從 1~%d 中輸入一組六個號碼(不可重複):\n", MAX);
fflush(stdin);
} while (scanf("%d%d%d%d%d%d",&a[0],&a[1],&a[2],&a[3],&a[4],&a[5])<6);
do {
printf("再輸入一組六個號碼(不可重複):\n");
fflush(stdin);
} while (scanf("%d%d%d%d%d%d",&b[0],&b[1],&b[2],&b[3],&b[4],&b[5])<6);
printf("\n");
} while (check(a, b));
//把 1~48中排除 a[0]~a[5] 的42個數字置入box[0]~box[41]
//box[42]~box[47]未使用
for (m=0,i=1; i<=MAX; i++){
for (j=0; j<6; j++)
if (i==a[j]) break;
if (j==6) box[m++]=i;
}
srand((unsigned)time(NULL));
int ok=0;
for (m=0; m<10; m++){
//打亂 box[ ]的順序
for (i=MAX-6-1; i>1; i--){
j=rand()/(double)(RAND_MAX+1) * i; //j=rand()%i
tmp=box[j]; box[j]=box[i]; box[i]=tmp;
}
//從box[first]起挑6個數,故first應小於 MAX-6-6
int first=rand()%(MAX-12+1);
for (i=0; i<6; i++) rand_a[m][i]=box[first+i];
//若此6個數未含第二組的數字,則任選一個替換
for (ok=0,i=0; i<6; i++) {
for (j=0; j<6; j++)
if (rand_a[m][i]==b[j]) {ok=1; i=6; break;}
}
if (!ok)
{ j=rand()%6; rand_a[m][j]=b[j];}
}
for(m=0; m<10; m++){//輸出十組亂數
for(i=0; i<6; i++){
printf("%2d ",rand_a[m][i]);
}
printf("\n");
}
system("Pause");
return 0;
}
2009-04-05 21:00:37 補充:
//續上
//檢驗輸入是否合乎規定: 正確,傳回 0;不正確,傳回非零值
int check(int a[], int b[])
{
int i, j, error=0;
2009-04-05 21:01:29 補充:
for (i=5;i>-1;i--)
{
for (j=i-1;j>-1;j--)
if (a[i]==a[j]) { error |= 1; break; }
for (j=i-1;j>-1;j--)
if (b[i]==b[j]) { error |= 2; break; }
for (j=0; j<6; j++)
if (a[i]==b[j]) { error |= 4; break; }
2009-04-05 21:02:12 補充:
if (a[i]<1 || a[i]>MAX || b[i]<1 || b[i]>MAX) error |= 8;
}
if (error & 1) printf("第一組數字重複輸入\n");
if (error & 2) printf("第二組數字重複輸入\n");
if (error & 4) printf("第一組數字和第二組數字重複\n");
2009-04-05 21:02:33 補充:
if (error & 8) printf("輸入的數字某些不在 1~%d 區間內\n", MAX);
if (error) printf("\n輸入不合規定,請重新輸入!\n");
return error;
}
2009-04-05 21:05:55 補充:
爛知識+,字數限制只好分次完事,硬是把俺的內文打得七零八落。
2009-04-05 22:50:42 補充:
這個註解在匆忙中有所疏失:
//從box[first]起挑6個數,故first應小於 MAX-6-6
應修正為:
//從box[first]起挑6個數,故first應不大於 MAX-6-6
但程式相對應的部份則沒有錯。
2009-04-06 01:50:39 補充:
回覆再提問的問題:
問:.while (check(a, b));是撿查 a b 有無相同嗎~?
答:檢查 a,b是否有重複及是否其數字皆在1~48之間。
問:#define MAX 48
答:程式在編譯時的前置處理,會先把程式裡所有的 MAX都替換成 48。
這可使程式更有彈性,比如想擴大數字至60,只需把這裡的48改成60即可。
2009-04-06 01:54:41 補充:
問:srand((unsigned)time(NULL)); 的 unsigned加了有什麼功用~?
答:srand 函式接收的引數是unsigned ,所以加這個是為了要符合函式原型。
2009-04-06 02:07:33 補充:
問:
for (i=MAX-6-1; i>1; i--){
j=rand()/(double)(RAND_MAX+1) * i; //j=rand()%i
tmp=box[j]; box[j]=box[i]; box[i]=tmp;
2009-04-06 02:07:42 補充:
答:一般是用rand()%i,但用rand()/(double)(RAND_MAX+1) * i可得到比較亂的亂數,兩者都可產生 0~i-1。你可改用註解後的一般式j=rand()%i,比較簡易。
第一次,i=41,假設j取得亂數15,box[41]和box[15]互換。
第二次,i=40,假設j取得亂數22,box[40]和box[22]互換。
......如此,便可打亂其序。
2009-04-06 02:09:16 補充:
問:
for (m=0,i=1; i<=MAX; i++){
for (j=0; j<6; j++)
if (i==a[j]) break;
if (j==6) box[m++]=i;
}
2009-04-06 02:22:16 補充:
答:
for (j=0; j<6; j++) if (i==a[j]) break;
若 i==a[j]將離開 j迴圈,此時j因中途結束迴圈,故必小於6。
所以在迴圈結束後,可用j來辨別i==a[j]是否曾成立過,
if (j==6) 若成立,表示迴圈整個完成,i==a[j]未曾成立過,
i這個數不在a之中,便把它加入box內。
m是計次,也是指引box陣列的足標,把i存入,當然用box[m++]=i;(不是box[m++]==i;)
box[m++]=i; 相當於 box[m]=i; m++;