線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:2410
推到 Plurk!
推到 Facebook!

關於產生數個不同的亂數........

答題得分者是:geniustom
A_DALA
一般會員


發表:1
回覆:1
積分:0
註冊:2004-10-25

發送簡訊給我
#1 引用回覆 回覆 發表時間:2004-11-11 21:41:57 IP:211.21.xxx.xxx 未訂閱
想請問各位: 我所想問的問題是,假使已達成產生了一個1到100的亂數了,但如果想達到產生五個不同1到100間的亂數呢?? procedure TForm1.Button1Click(Sender: TObject); var r:integer; begin randomize; r:=random(42); edit1.text:=IntToStr(r); end; end. 上面是目前所學到的程度,也希望給予尚缺失的指點,不好意思請教各位了,謝謝..... 發表人 - A_DALA 於 2004/11/11 22:11:15
jeffreck
高階會員


發表:247
回覆:340
積分:197
註冊:2003-01-23

發送簡訊給我
#2 引用回覆 回覆 發表時間:2004-11-11 23:36:16 IP:61.70.xxx.xxx 未訂閱
http://delphi.ktop.com.tw/topic.php?topic_id=21479 http://delphi.ktop.com.tw/topic.php?topic_id=50217 Try Try see
A_DALA
一般會員


發表:1
回覆:1
積分:0
註冊:2004-10-25

發送簡訊給我
#3 引用回覆 回覆 發表時間:2004-11-12 00:38:46 IP:211.21.xxx.xxx 未訂閱
多謝指教.....謝謝.....
geniustom
版主


發表:100
回覆:303
積分:260
註冊:2003-01-03

發送簡訊給我
#4 引用回覆 回覆 發表時間:2004-11-12 22:42:17 IP:219.68.xxx.xxx 未訂閱
一般人看到【取亂數不重複】..很直接的想法就是一直取,每次取完之後在跟之前的比較.. 其實這樣的效率極差!取N個不重複的亂數需要做N階乘次比對.. 有學過資料結構的應該都知道..在複雜度裡面..N階乘算是【極差】 取亂數可以使用洗牌法.. 意思就是說.. 1..假設剛買來的牌..有52張..分別照順序排好... 2..你只需要把52張牌全部攤開..隨便選2張交換... 3..交換52次之後..可以做出很平均的亂數處理.. 所以..如果要產生A~B不重複的亂數..演算法如下..
var
    Nums: array of integer;
    i,j,k,temp: integer;
begin
    randomize; 灑下亂數種子
    setlength(Nums,B-A) //產生B-A張牌
    for i := 0 to (B-A)-1 do
        Nums[i] := i;    //產生一副新牌..都是照順序排好的
    for i := 0 to (B-A)-1 do 
    begin
        j := random(B-A 1); //隨便選兩張牌(索引) 取出0~(B-A)的亂數
        k := random(B-A 1);
        temp := Nums[j];     //交換兩張隨便取的牌
        Nums[j] := Nums[k];
        Nums[k] := temp;
    end;
    for i := 0 to (B-A)-1 do
        Nums[j]:=Nums[j] A; //最後..把這邊的排全部變成A~B的值
end;    假如您要取5個..
那只要選Nums[0]~Nums[4]..就是一組很漂亮的亂數..
效率極佳..只需要O(n)次...
而一般人想到那種差勁的演算法..差不多到100..程式就要死當了
供參考 =程式是一種藝術 也是訓練自己的分析規劃= =是段落分明 或是雜亂無章= =是一言以敝 或是廢話連篇= =是一目了然 或是艱深難懂= 體會這份藝術 您會了解另一份喜悅與成就 發表人 -
change.jian
版主


發表:29
回覆:620
積分:439
註冊:2003-06-02

發送簡訊給我
#5 引用回覆 回覆 發表時間:2004-11-12 23:20:16 IP:61.229.xxx.xxx 未訂閱
受教了 <>< face="Verdana, Arial, Helvetica">引言: 一般人看到【取亂數不重複】..很直接的想法就是一直取,每次取完之後在跟之前的比較.. 其實這樣的效率極差!取N個不重複的亂數需要做N階乘次比對.. 有學過資料結構的應該都知道..在複雜度裡面..N階乘算是【極差】 取亂數可以使用洗牌法.. 意思就是說.. 1..假設剛買來的牌..有52張..分別照順序排好... 2..你只需要把52張牌全部攤開..隨便選2張交換... 3..交換52次之後..可以做出很平均的亂數處理.. 所以..如果要產生A~B不重複的亂數..演算法如下..
var
    Nums: array of integer;
    i,j,k,temp: integer;
begin
    randomize; 灑下亂數種子
    setlength(Nums,B-A) //產生B-A張牌
    for i := 0 to (B-A)-1 do
        Nums[i] := i;    //產生一副新牌..都是照順序排好的
    for i := 0 to (B-A)-1 do 
    begin
        j := random(B-A 1); //隨便選兩張牌(索引) 取出0~(B-A)的亂數
        k := random(B-A 1);
        temp := Nums[j];     //交換兩張隨便取的牌
        Nums[j] := Nums[k];
        Nums[k] := temp;
    end;
    for i := 0 to (B-A)-1 do
        Nums[j]:=Nums[j] A; //最後..把這邊的排全部變成A~B的值
end;    假如您要取5個..
那只要選Nums[0]~Nums[4]..就是一組很漂亮的亂數..
效率極佳..只需要O(n)次...
而一般人想到那種差勁的演算法..差不多到100..程式就要死當了
供參考 =程式是一種藝術 也是訓練自己的分析規劃= =是段落分明 或是雜亂無章= =是一言以敝 或是廢話連篇= =是一目了然 或是艱深難懂= 體會這份藝術 您會了解另一份喜悅與成就 發表人 - >< face="Verdana, Arial, Helvetica">
jeffreck
高階會員


發表:247
回覆:340
積分:197
註冊:2003-01-23

發送簡訊給我
#6 引用回覆 回覆 發表時間:2004-11-13 12:32:15 IP:61.218.xxx.xxx 未訂閱
原來還有這樣的作法,太神了
visor
一般會員


發表:5
回覆:12
積分:3
註冊:2003-09-09

發送簡訊給我
#7 引用回覆 回覆 發表時間:2005-02-07 00:24:14 IP:61.217.xxx.xxx 未訂閱
這樣的做法並不是最好的  有更好的做法可以將牌洗的更亂 複雜度也是 O(n) 假設我們有 52 張牌    srand(time(NULL));        //取亂數種子 for(i=0;i<52;i ) num[i] = i 1; //初始化 52 張牌 1~52 for(i=0;i<52;i ) //洗牌動作 { j = rand()R; //隨機取 0~51 當索引 tmp = num[i]; //交換兩張牌 num[i] = num[j]; num[j] = tmp; } 這樣子 num[] 就已經是一個不重覆且是雜亂的陣列了 你要取幾張牌 只要從頭開始取就可以了 演算法概要 首先需要兩組 index i,j i 從 0~51 j 則是隨機 0~51 取出後做交換 這樣子每張牌都跟隨機一張牌做過交換動作 就可以達成洗牌動作了 -- Visor 元智大學資訊工程所
系統時間:2017-12-14 4:41:34
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!