C++的程式問題 亂數取數在篩選

2009-04-05 8:04 am
任意輸入兩組六個1~48的數字 再亂數取十組6個數字 均與第一組自取數字不相同 至少包含一個第二組數字自取數字

#include "stdafx.h"
#include < stdio.h >
#include < stdlib.h >
#include < time.h >



int main(int argc, char* argv[])
{
int a[6] , b[6] ,rand_a[10][6] ,i ,j ,l, m ,n;

printf("從1~48中輸入一組六個號碼 不可重複:\n");
scanf("%d%d%d%d%d%d",&a[0],&a[1],&a[2],&a[3],&a[4],&a[5]);
printf("再輸入一組六個號碼 不可重複:\n");
scanf("%d%d%d%d%d%d",&b[0],&b[1],&b[2],&b[3],&b[4],&b[5]);

for(i=5;i>=0;i--){//檢查有無輸入錯誤
for(j=i-1;j>=0;j--){
if(a[i]==a[j])
printf("妳重複輸入了第一組數字\n");
if(b[i]==b[j])
printf("妳重複輸入了第二組數字\n");
if(a[i]>48 || b[i]>48)
printf("你輸入的數字大於48");

}
}

srand(time(NULL));
for(l=0;l<=9;l++){
rand_a[l][0]=1+rand()%48;//取一組的第一個亂數
for(i=1;i<=5;i++){
rand_a[l][i]=1+rand()%48;
for(j=i-1;j>-1;j--){
if(rand_a[l][i]==rand_a[l][j])//同一組內重覆的話重找
i--;
}
for(m=0;m<=5;m++){
if(rand_a[l][i]==a[m] || rand_a[l][0]==a[m])//如果一組內有跟自取第一組的內數字相同 重找
i--;
}
for(n=0;n<=5;n++){
if(b[n]==rand_a[l][i] || b[n]==rand_a[l][0])//如果一組內都沒有跟自取第二組相同數字的話重找
break;
else
i--;
}








}
}


for(l=1;l<=10;l++){//輸出十組亂數
for(i=0;i<=5;i++){
printf("%d ",rand_a[l-1][i]);

}
printf("\n");
}



system("Pause");











return 0;
}
這是我自己寫的
可是就是執行不了
好像在第二個條件那邊卡住(與第二組至少一相同)

可以幫我找BUG嗎~?
更新1:

有問題 while (check(a, b)); 是撿查 a b 有無相同嗎~? #define MAX 48 這是什麼? srand((unsigned)time(NULL)); 的 unsigned 加了有什麼功用~?

更新2:

//打亂 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; 這段 我也看不懂 if (j==6) box[m++]=i; 這是說啥= = 為啥不是box[m++]==i 而是 box[m++]=i

回答 (4)

2009-04-06 4:55 am
✔ 最佳答案
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++;
2009-04-06 3:32 am
啊咧~

版大名字裡有個〝刖〞,
這意見 003 ……

還是島主您最近又練了什麼神功?
2009-04-06 3:10 am
東邪 可以幫我改寫出個範例給我看嗎~?

我想知道 到底要怎麼架構才好

因為我是初學者

只會亂拼湊= =

拜託了~>
2009-04-06 1:23 am
打掉重建?!那就是「砍掉重練」了吧?XD~~~


收錄日期: 2021-04-28 23:06:48
原文連結 [永久失效]:
https://hk.answers.yahoo.com/question/index?qid=20090405000016KK00050

檢視 Wayback Machine 備份