伊莉討論區
標題:
樂透 1~46數字 隨機選出六個但不可重複 須做前置計算
[打印本頁]
作者:
inmax1243
時間:
2011-12-29 10:32 PM
標題:
樂透 1~46數字 隨機選出六個但不可重複 須做前置計算
樂透 1~46數字 隨機選出六個但不可重複 須做前置計算
目前卡在 要隨機輸出 不可以重複 (須在程式執行前先寫一個c 在寫程式的時候呼叫原本寫好的c 進行記憶體位子儲存)
void gen(int max,int mun,int*x)需要用到這個函式 前置作業須做一個c 在程式中呼應寫好的c
計算六個數字
_____________________________________________________________
malloc(sizeof(int)*num) 須使用這個函式 做為每次儲存記憶體位子
計算後需要6個數字不重複+依大小排列
個人有參考他人寫過的c 不過 不知要如何下手 將程式寫到完
個人寫的c 還是有點問題 無法執行 加入malloc gen條件我就不會寫了...
作者:
baepi
時間:
2011-12-31 12:48 AM
本帖最後由 baepi 於 2011-12-31 12:55 AM 編輯
老實說~看完大大的說明...我就嘗試寫了一下(很久沒寫c了~抱歉)
所以...並沒有抓大大的檔案來看...所以也不確定自己給的是否對大大有幫助
因此如果小的會錯意...大大可以文字糾正一下
~以上
以下是寫的文字碼加上我行我素的解釋
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void gen(int max,int num,int *x)
{
srand( time(NULL) );
if(max!=0)
{ //隨機產生亂數且不能重複~我選擇用陣列抓字的方式
int *number = (int*)malloc(sizeof(int)*max); //產生長度為46的一維陣列
for(int i=0;i<max;i++)
number[i]=i+1; //將裡面的依序填值
int buffer; //單純拿來暫存~轉換資料用
for(int i=0;i<num;i++) //此處就是前面說的...陣列抓字
{
buffer = (rand() % (max-i));
x[i] = number[buffer];
for(int j=buffer;j<(max-i);j++)
number[j]=number[j+1];
}
for(int i=0;i<num;i++) //由大到小排列
for(int j=0;j<(num-i);j++)
if(x[j]<x[j+1])
{
buffer=x[j];
x[j]=x[j+1];
x[j+1]=buffer;
}
free(number); //釋放長度46的一維陣列
}
}
int main()
{
int num=6,max=46;
if(num!=0)
{
int *x = (int*)malloc(sizeof(int)*num); //產生長度為6的一維陣列
gen(max,num,x);
for(int i=0;i<num;i++)
p rintf("%d\n",x[i]); //輸出
free(x); //印象中都要釋放
}
return 0;
}
複製代碼
作者:
inmax1243
時間:
2011-12-31 02:31 AM
本帖最後由 inmax1243 於 2011-12-31 03:13 AM 編輯
回復
2#
baepi
回復 2# baepi
baepi感謝大大幫忙有寫註解 這樣我比較清楚
目前本人在學淺層C 某些部分還是不太懂
執行起來好像有錯誤 好像I沒有定義 要如何修改
[attach]68074031[/attach]
剛好在參考書上面看到這種例題 突然不知該怎樣做答 只提示作法骰子一樣
其實題目正確名稱是1~46支籤(我把它想成樂透) 隨機抽取六支 數字不可以重複
必須使用指標來告訴出現的數字的位子
剛好在參考書上面看到這種例題 突然不知該怎樣做答 只提示作法骰子一樣
參考書 提示
要做類似骰子6個數值 每次甩毀有不同數字出來 須在甩後相同數直不可以出現
並且要用x儲存六個數字 指標指定位子 每次結果要不一樣
最後使用for if 映出大小排列
個人寫的狀況 不過我不知道指標要怎樣使用 void gen(int max,int mun,int*x)需要用到這個函式
前置作業須做一個c 這部分可能要多練習了.....
這樣執行式OK的 不過沒用到指標...
[attach]68073629[/attach]
作者:
inmax1243
時間:
2011-12-31 03:17 AM
老實說~看完大大的說明...我就嘗試寫了一下(很久沒寫c了~抱歉)
所以...並沒有抓大大的檔案來看...所以也不 ...
baepi 發表於 2011-12-31 12:48 AM
SP:本人最近才開始接觸C略有不懂 感請大大指教一下
我比較擅長PE3.1 V5.2 DOS底下作業模式 比較屬於後台軟體部分
作者:
baepi
時間:
2011-12-31 12:27 PM
回復
3#
inmax1243
恩...抱歉...因為太久沒寫c....好吧~我承認這是藉口^^
為什麼i跟j會沒有定義呢...因為好像c不能這樣寫(根據我用flow code的印象)
所以應該改成...我把程式碼整個再重貼一次吧
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void gen(int max,int num,int *x)
{
srand( time(NULL) );
if(max!=0)
{ //隨機產生亂數且不能重複~我選擇用陣列抓字的方式
int i,j; //在for迴圈使用前就要先宣告...用vc++寫久了~忘了這東西了
int *number = (int*)malloc(sizeof(int)*max); //產生長度為46的一維陣列
for(i=0;i<max;i++)
number[i]=i+1; //將裡面的依序填值
int buffer; //單純拿來暫存~轉換資料用
for(i=0;i<num;i++) //此處就是前面說的...陣列抓字
{
buffer = (rand() % (max-i));
x[i] = number[buffer];
for(j=buffer;j<(max-i);j++)
number[j]=number[j+1];
}
for(i=0;i<num;i++) //由大到小排列
for(int j=0;j<(num-i);j++)
if(x[j]<x[j+1])
{
buffer=x[j];
x[j]=x[j+1];
x[j+1]=buffer;
}
free(number); //釋放長度46的一維陣列
}
}
int main()
{
int i;
int num=6,max=46;
if(num!=0)
{
int *x = (int*)malloc(sizeof(int)*num); //產生長度為6的一維陣列
gen(max,num,x);
for(i=0;i<num;i++)
p rintf("%d\n",x[i]); //輸出
free(x); //印象中都要釋放
}
return 0;
}
複製代碼
另外...大大貼的亂數且不重複的方法...是屬於比較不佔記憶體~但是實際跑的時候次數未知...
因為產生亂數且發現重複則重新產生...所以運作效能難以捉摸
而小弟給的方法是屬於耗費不小的記憶體空間(看亂數範圍)~但是亂數產生只會跑六次(以我這範例來說)....因此運作效能我比較能掌握...個人偏好這種
作者:
inmax1243
時間:
2011-12-31 03:08 PM
回復
5#
baepi
baepi感謝大大幫忙 我大概知道我自己問題出在哪了
一.設定指定位子給變數一個空間(計算用)
二.利用指標功能呼叫設定空間出來給他儲存
三.利用變數指向輸出的值
四.指標與陣列 使用比較不同 陣列須要有規則性 指標比寬鬆可以指定計算後輸出的值
五.可能寫C要注意一下占存記憶體位子 比較不會零亂
作者:
inmax1243
時間:
2011-12-31 03:17 PM
本帖最後由 inmax1243 於 2011-12-31 03:19 PM 編輯
回復
5#
baepi
那個人再問一個問題 若如果指定 要開出來的數字 要如何讓他 跳出來
我只知道要使用break跳出
題目
寫一程式,輸入樂透號碼數值範圍max與開獎號碼數n個,製作一個函式gen(int max, int n, int *x)會產生n個不重複的範圍內亂數,存入x指標變數所指的空間內。
並在主程式內呼叫gen函式,並將開獎號碼印出
Ex:
要求
一.輸入樂透號碼數值範圍:46
二.輸入開獎號碼數:6
三.產生之開獎號碼:4, 43, 23, 33, 12, 22
目前知道1~2會做了 3的話指定輸出的數字 不太了解要怎樣讓他輸出我要的值
sp: for作 i++ or (n-1) 利用if好像也沒辦法印出來
這部分可能要問一下
作者:
baepi
時間:
2011-12-31 03:56 PM
回復
7#
inmax1243
對不起~老實說~不是很懂大大的問題是出在哪裡
什麼是指定輸出數字?
以下是我的猜想...另外~void gen的部分我就不貼了...減少版面空間...因為只改到main的部分
int main()
{
int i,j;
int num=6,max=46;
if(num!=0)
{
int user_num[6];
for(i=0;i<6;i++)
{
p rintf("請輸入第%d個號碼:",i+1);
scanf("%d", &user_num[i]);
}
int *x = (int*)malloc(sizeof(int)*num); //產生長度為6的一維陣列
gen(max,num,x);
p rintf("開獎號碼為: ");
for(i=0;i<num;i++)
p rintf("%d\t",x[i]); //輸出開獎號碼
p rintf("\n押注號碼為: ");
for(i=0;i<num;i++)
p rintf("%d\t",user_num[i]); //輸出押注號碼
p rintf("\n猜中號碼為: ");
for(i=0;i<num;i++)
for(j=0;j<num;j++)
if(x[i]==user_num[j])
{
p rintf("%d\t",x[i]);
}
free(x); //印象中都要釋放
}
return 0;
}
複製代碼
作者:
inmax1243
時間:
2011-12-31 04:45 PM
本帖最後由 inmax1243 於 2011-12-31 05:15 PM 編輯
一.輸入樂透號碼數值範圍:46
二.輸入開獎號碼數:6
void gen 此處 已經感謝大大的教導 已經會寫了
____________________________________________
三.產生之開獎號碼:4, 43, 23, 33, 12, 22
其實參考書有解答 不過我不懂參考書的意思 若有中文解釋意思 我學C會比較清楚變化過程
最後再向你請教一次 輸入任何數字 或 不輸入任何數字 執行完 (我理解理對參考書有點差)
會出現這六個數字 4, 43, 23, 33, 12, 22 (此處=我最後要的結果)
要再main裡面要做哪些動作 才可以將這六個開獎數字印出來(最後輸出)
作者:
inmax1243
時間:
2011-12-31 05:39 PM
本帖最後由 inmax1243 於 2011-12-31 05:45 PM 編輯
回復
8#
baepi
第五樓修改 for() 排大小 應該沒有int 不然會錯誤
跑完一次程式 會當掉 可能無窮迴圈
個人是使用eclipse 此軟體寫程式 不知與你使用的程式 執行結果起來式是否有差異
作者:
baepi
時間:
2011-12-31 09:00 PM
回復
10#
inmax1243
恩...大大說for迴圈的int~確實是漏砍的...因為在c++裡面~我都習慣這麼寫
畢竟~一個變數一直濫用~到最後都會不知道那東西是幹嘛的(這是我寫大程式的經驗)
尤其a專案抓b專案時...有時會遇到
可是在c底下好像不能這麼用orz
另外..大大說用我寫的程式~會當掉?
怪怪~我最初一開始貼的時候...曾經用for迴圈跑過10萬次(因為檢查有沒有bug)
那時都沒問題的說....我是用vc2005寫的...eclipse我只拿來寫android
不過我覺得...應該跟用哪個程式沒關係...恩~我不知道...裡面也沒無限迴圈阿
作者:
inmax1243
時間:
2011-12-31 09:46 PM
回復
11#
baepi
謝謝你的幫忙
摁 我在看是我哪邊的問題 因為我顯示跑一次 第一個值不是我要的值
後面五的=我要的值 有做排列 是正確的 目前還在想 這是期末考考題...
這題會了 這個學期ALL PASS 不會要重修 目前還在專研C 還有幾天時間可以讓我慢慢想
我還在摸索中 摸熟後再多換幾套程式編輯軟體玩看看 可能每套軟體設定方式大同小異
作者:
inmax1243
時間:
2012-1-1 02:34 AM
本帖最後由 inmax1243 於 2012-1-1 01:12 PM 編輯
回復
11#
baepi
最後做出來的結果 雖然與參考書雷同 不過還在想有沒有其他作法
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void gen(int max,int num,int *x)
{
int i,j,b,sp[num];
srand(time(NULL));
for(i=0;i<num;i++)
{
b=rand()%max+1;
for(j=0;j<i;j++)
{
if(sp[j]==b)
{
j=-1;
b=rand()%max+1;
}
}
sp=b;
*(x+i)=sp;
}
}
int main(int argc, char *argv[])
{
int i,num=6,*y;
y=(int*)malloc(sizeof(int)*num);
gen(46,num,y);
for(i=0;i<num;i++)
p rintf("%d \n",*(y+i));
system("pause");
return 1;
}
複製代碼
作者:
baepi
時間:
2012-1-2 10:52 AM
恩...不好意思~因為vc2005並不能支援像sp[num]這樣的宣告(因為他無法確保)num會不為0
所以我直接把他砍掉(因為感覺用不到)
另外~大大果然還是選擇隨機產生...那程式碼應該能稍微改的簡單點...而且檢查方法雖然看起來很快~但是有漏洞
就是大大寫的
if(sp[j]==b)
{
j=-1;
b=rand()%max+1;
}
複製代碼
因為假設開獎號碼為1 2 3 4
然後當大大第五次搖出號碼為3....那麼會再第3次檢查時重新產生變數~但若是此次產生變數為1...那漏洞就產生了
所以...小的修改為~以下
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void gen(int max,int num,int *x)
{
int i,j=0,b;
srand(time(NULL));
for(i=0;i<num;i++)
{
b=rand()%max+1;
for(j=0;j<i;j++)
{
if(x[j]==b)
{
--i;
j=-1; //j為-1表示有重複的數值~所以要重新產生亂數
break;
}
}
if(j!=-1)
{
x[i]=b;
}
}
}
int main(int argc, char *argv[])
{
int i,num=6,*y;
y=(int*)malloc(sizeof(int)*num);
gen(46,num,y);
for(i=0;i<num;i++)
p rintf("%d \n",*(y+i));
free(y); //我印象中要把這記憶體空間釋放掉...不然假如這程式一直循環執行...會佔用越來越多記憶體~當然這程式不會~因為這程式到此就結束了~只是好習慣應該常常培養
system("pause");
return 1;
}
複製代碼
作者:
inmax1243
時間:
2012-1-2 01:13 PM
回復
14#
baepi
baepi 多謝幫忙 我再回去多練習幾次 想看看還有沒比較好的方法可以寫出相同的內容
我寫的方式是隨機產生沒錯(記憶體本身會用比較大去運行)
因為我不太會用固定模式(最小指定位子) 新手 比較不了精深寫法沒辦法運用得很順暢
可能我參考書要再多買幾本 熟悉一下不同的寫法 比較能運用自如
歡迎光臨 伊莉討論區 (http://a401.file-static.com/)
Powered by Discuz!