伊莉討論區

標題: 樂透 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了~抱歉)
所以...並沒有抓大大的檔案來看...所以也不確定自己給的是否對大大有幫助
因此如果小的會錯意...大大可以文字糾正一下
~以上
以下是寫的文字碼加上我行我素的解釋
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <time.h>
  4. void gen(int max,int num,int *x)
  5. {
  6.         srand( time(NULL) );
  7.         if(max!=0)
  8.         {        //隨機產生亂數且不能重複~我選擇用陣列抓字的方式
  9.                 int *number = (int*)malloc(sizeof(int)*max);        //產生長度為46的一維陣列
  10.                 for(int i=0;i<max;i++)
  11.                         number[i]=i+1;        //將裡面的依序填值

  12.                 int buffer;        //單純拿來暫存~轉換資料用
  13.                 for(int i=0;i<num;i++)        //此處就是前面說的...陣列抓字
  14.                 {
  15.                         buffer = (rand() % (max-i));
  16.                         x[i] = number[buffer];
  17.                         for(int j=buffer;j<(max-i);j++)
  18.                                 number[j]=number[j+1];
  19.                 }

  20.                 for(int i=0;i<num;i++)        //由大到小排列
  21.                         for(int j=0;j<(num-i);j++)
  22.                                 if(x[j]<x[j+1])
  23.                                 {
  24.                                         buffer=x[j];
  25.                                         x[j]=x[j+1];
  26.                                         x[j+1]=buffer;
  27.                                 }

  28.                 free(number);        //釋放長度46的一維陣列
  29.         }
  30. }
  31. int main()
  32. {
  33.         int num=6,max=46;
  34.         if(num!=0)
  35.         {
  36.                 int *x = (int*)malloc(sizeof(int)*num);        //產生長度為6的一維陣列
  37.                 gen(max,num,x);
  38.                 for(int i=0;i<num;i++)
  39.                 p rintf("%d\n",x[i]);        //輸出
  40.                 free(x);        //印象中都要釋放
  41.         }
  42.         return 0;
  43. }
複製代碼

作者: 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的印象)
所以應該改成...我把程式碼整個再重貼一次吧
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <time.h>
  4. void gen(int max,int num,int *x)
  5. {
  6.         srand( time(NULL) );
  7.         if(max!=0)
  8.         {        //隨機產生亂數且不能重複~我選擇用陣列抓字的方式

  9.                 int i,j;        //在for迴圈使用前就要先宣告...用vc++寫久了~忘了這東西了

  10.                 int *number = (int*)malloc(sizeof(int)*max);        //產生長度為46的一維陣列
  11.                 for(i=0;i<max;i++)
  12.                         number[i]=i+1;        //將裡面的依序填值

  13.                 int buffer;        //單純拿來暫存~轉換資料用
  14.                 for(i=0;i<num;i++)        //此處就是前面說的...陣列抓字
  15.                 {
  16.                         buffer = (rand() % (max-i));
  17.                         x[i] = number[buffer];
  18.                         for(j=buffer;j<(max-i);j++)
  19.                                 number[j]=number[j+1];
  20.                 }

  21.                 for(i=0;i<num;i++)        //由大到小排列
  22.                         for(int j=0;j<(num-i);j++)
  23.                                 if(x[j]<x[j+1])
  24.                                 {
  25.                                         buffer=x[j];
  26.                                         x[j]=x[j+1];
  27.                                         x[j+1]=buffer;
  28.                                 }

  29.                 free(number);        //釋放長度46的一維陣列
  30.         }
  31. }
  32. int main()
  33. {
  34.         int i;
  35.         int num=6,max=46;
  36.         if(num!=0)
  37.         {
  38.                 int *x = (int*)malloc(sizeof(int)*num);        //產生長度為6的一維陣列
  39.                 gen(max,num,x);
  40.                 for(i=0;i<num;i++)
  41.                 p rintf("%d\n",x[i]);        //輸出
  42.                 free(x);        //印象中都要釋放
  43.         }
  44.         return 0;
  45. }
複製代碼
另外...大大貼的亂數且不重複的方法...是屬於比較不佔記憶體~但是實際跑的時候次數未知...
因為產生亂數且發現重複則重新產生...所以運作效能難以捉摸
而小弟給的方法是屬於耗費不小的記憶體空間(看亂數範圍)~但是亂數產生只會跑六次(以我這範例來說)....因此運作效能我比較能掌握...個人偏好這種
作者: 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的部分
  1. int main()
  2. {
  3.         int i,j;
  4.         int num=6,max=46;
  5.         if(num!=0)
  6.         {
  7.                 int user_num[6];
  8.                 for(i=0;i<6;i++)
  9.                 {
  10.                         p rintf("請輸入第%d個號碼:",i+1);
  11.                         scanf("%d", &user_num[i]);
  12.                 }


  13.                 int *x = (int*)malloc(sizeof(int)*num);        //產生長度為6的一維陣列
  14.                 gen(max,num,x);

  15.                 p rintf("開獎號碼為: ");
  16.                 for(i=0;i<num;i++)
  17.                         p rintf("%d\t",x[i]);        //輸出開獎號碼

  18.                 p rintf("\n押注號碼為: ");
  19.                 for(i=0;i<num;i++)
  20.                         p rintf("%d\t",user_num[i]);        //輸出押注號碼

  21.                 p rintf("\n猜中號碼為: ");
  22.                 for(i=0;i<num;i++)
  23.                         for(j=0;j<num;j++)
  24.                                 if(x[i]==user_num[j])
  25.                                 {
  26.                                         p rintf("%d\t",x[i]);
  27.                                 }
  28.                
  29.                 free(x);        //印象中都要釋放
  30.         }
  31.         return 0;
  32. }
複製代碼

作者: 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

最後做出來的結果 雖然與參考書雷同 不過還在想有沒有其他作法
  1.     #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <time.h>
  4. void gen(int max,int num,int *x)
  5. {
  6. int i,j,b,sp[num];
  7. srand(time(NULL));
  8. for(i=0;i<num;i++)
  9. {
  10. b=rand()%max+1;
  11. for(j=0;j<i;j++)
  12. {
  13. if(sp[j]==b)
  14. {
  15. j=-1;
  16. b=rand()%max+1;
  17. }
  18. }
  19. sp=b;
  20. *(x+i)=sp;
  21. }
  22. }
  23. int main(int argc, char *argv[])
  24. {
  25. int i,num=6,*y;
  26. y=(int*)malloc(sizeof(int)*num);
  27. gen(46,num,y);
  28. for(i=0;i<num;i++)
  29. p rintf("%d \n",*(y+i));
  30. system("pause");
  31. return 1;
  32. }
複製代碼

作者: baepi    時間: 2012-1-2 10:52 AM

恩...不好意思~因為vc2005並不能支援像sp[num]這樣的宣告(因為他無法確保)num會不為0
所以我直接把他砍掉(因為感覺用不到)
另外~大大果然還是選擇隨機產生...那程式碼應該能稍微改的簡單點...而且檢查方法雖然看起來很快~但是有漏洞
就是大大寫的
  1. if(sp[j]==b)
  2. {
  3. j=-1;
  4. b=rand()%max+1;
  5. }
複製代碼
因為假設開獎號碼為1 2 3 4
然後當大大第五次搖出號碼為3....那麼會再第3次檢查時重新產生變數~但若是此次產生變數為1...那漏洞就產生了
所以...小的修改為~以下
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <time.h>
  4. void gen(int max,int num,int *x)
  5. {
  6.         int i,j=0,b;
  7.         srand(time(NULL));
  8.         for(i=0;i<num;i++)
  9.         {
  10.                 b=rand()%max+1;
  11.                 for(j=0;j<i;j++)
  12.                 {
  13.                         if(x[j]==b)
  14.                         {
  15.                                 --i;
  16.                                 j=-1;        //j為-1表示有重複的數值~所以要重新產生亂數
  17.                                 break;
  18.                         }
  19.                 }
  20.                 if(j!=-1)
  21.                 {
  22.                         x[i]=b;
  23.                 }
  24.         }
  25. }
  26. int main(int argc, char *argv[])
  27. {
  28. int i,num=6,*y;
  29. y=(int*)malloc(sizeof(int)*num);
  30. gen(46,num,y);
  31. for(i=0;i<num;i++)
  32. p rintf("%d \n",*(y+i));
  33. free(y);        //我印象中要把這記憶體空間釋放掉...不然假如這程式一直循環執行...會佔用越來越多記憶體~當然這程式不會~因為這程式到此就結束了~只是好習慣應該常常培養
  34. system("pause");
  35. return 1;
  36. }
複製代碼

作者: inmax1243    時間: 2012-1-2 01:13 PM

回復 14# baepi


    baepi 多謝幫忙 我再回去多練習幾次 想看看還有沒比較好的方法可以寫出相同的內容
我寫的方式是隨機產生沒錯(記憶體本身會用比較大去運行)
因為我不太會用固定模式(最小指定位子) 新手 比較不了精深寫法沒辦法運用得很順暢
可能我參考書要再多買幾本 熟悉一下不同的寫法 比較能運用自如




歡迎光臨 伊莉討論區 (http://a401.file-static.com/) Powered by Discuz!