- 積分
- 163
- 最後登入
- 1970-1-1
- 閱讀權限
- 50
- 積分
- 163
- 帖子
- 精華
升級
100%
|
本帖最後由 edisonx 於 2012-11-27 17:52 編輯
來個有建設性的發言好了。
setHidden 是遞迴,但「有機率」會產生 stack overflow 造成程式錯誤。今天換個偏激一點的問題:從 1~100000 產生 99998 個不重覆亂數怎麼跑?拿原本的寫法很容易寫到掛 (stack overflow)。
我們重新定義這個問題
整數從 A 到 B (含 A 含 B),範圍是 RANGE ( RANGE = B-A+1) ,如何產生 N (N<=RANGE) 個不重覆亂數?
ad6543210 給了一份 solution ,在針對 ( N / RANGE ) 比值較小的時候,用該法是首選,若 N / RANGE 較大時,該法會跑很慢,一般會將它包成副函式去做
- #include <stdio.h>
- #include <stdlib.h>
- #include <time.h>
- // random(low, up) pick #n, save result to rst
- void rand_force(int low, int up, int *rst, int n)
- {
- int j, count;
- int range = up-low+1;
- int rnd;
- for(count=0;count<n ; ){
- rnd = rand() % range + low;
- for(j=0; j<count && rst[j]!=rnd; ++j);
- if(j==count) rst[count++] = rnd;
- }
- }
- int main()
- {
- const int low = -5;
- const int up = 32760;
- const int N = up-low;
- int rst[32768];
- clock_t ck;
- srand( (unsigned)time(NULL));
- ck = clock();
- rand_force(low,up,rst,N);
- printf("td = %ld\n", clock()-ck);
- return 0;
- }
複製代碼 可以跑跑,上面給的例子很極端,所以跑得較慢。
另 rand_force 只有兩點要注意 : (1) range 必須 <= RAND_MAX (2) 適用整數,當然這兩點是可以修正的。
另一種方式叫 shuffle,洗牌法。先產生 int poker[up-low+1],填入數字,再隨機交換。
- void shuffle(int low, int up, int *rst, int n)
- {
- int rng = up - low + 1;
- int i, pos, t;
- int * poker = (int*) malloc(sizeof(int) * rng);
- for(i=low; i<=up; ++i) poker[i-lower] = i; // generat a poker
- for(i=0; i<rng; ++i){
- pos = rand() % rng;
- t = poker[i], poker[i] = poker[pos] , poker[pos] = t; // swap(poker[i], poker[pos])
- }
- // pick first n from poker to rst
- for(i=0; i<n; ++i) rst[i] = poker[i];
- free(poker);
- }
複製代碼 概念上是這樣,洗牌的方式有很多種,但 唯一經過「亂數均勻」測試的是 kunth shuffle,從後面洗回來,這個到 wiki 可以看到說明,就不再附碼了。
另外指標是真的很好用沒錯,但 p[ i ] 和 *(p+i) 其實根本就沒差,在低階 (翻成組語後) 做的事情是一模一樣的。如果有 polling 一份 array的話
- int arr[4] = {1,2,3,4};
- for(i=0; i<4; ++i) arr[i];
- for(i=0; i<4; ++i) *(arr+i);
複製代碼 這兩個作法是一模一樣的,有差別的是下面這種
- int arr[4] = {1,2,3,4};
- int *beg = arr , *end = arr+4;
- while(beg!=end){
- *beg ; \\ output
- ++beg;
- }
複製代碼 這在低階之處理才和上面兩種不同,至於指標其他的作法實在是不勝玫舉,有機會再討論。
一點意見參考,其他再嘴炮的東西 (如設計架構等,這個就見人見智,只是架構規劃的人可以規劃得更好),我就不說了。 |
|