- 算法競賽寶典(第一部):語言及算法入門
- 張新華
- 461字
- 2021-03-19 19:27:47
產生隨機數據
有些測試數據必須手工制作,以防止某些特例的出現,但是除此之外的多數測試數據,如果能寫一個程序自動產生該有多好!這顯然需要隨機數函數的幫忙了。
【例題描述】 趣味搖獎機
魔法學院舉行游園活動,為了烘托節日氣氛,決定在活動中設一個如圖3.7所示的趣味搖獎機,游戲規則如下:計算機在0~9十個數字中隨機取出一個數,由學生去猜,猜中的獲特等獎,相差一個數的,獲一等獎,相差兩個數的,獲二等獎,相差三個數的獲三等獎,其余的沒有獎。現在,請你來編寫這個程序實現這個功能。

圖3.7
參考程序如下所示:
1 //最容易實現的隨機數 2 #include <iostream> 3 #include <stdlib.h> //C語言中常用的頭文件,包含了常用的系統函數 4 #include <time.h> //必須使用time類的頭文件 5 using namespace std; 6 7 int main() 8 { 9 int i,j; 10 int t=time(0)%10; //以時間作為隨機函數 11 12 cout<<" **趣味搖獎機*** \n\n"; 13 cout<<"請任選一個數字(0-9): "; 14 15 cin>>j; 16 17 if(j<0 || j>9) 18 return 0; 19 20 if(j==t) 21 cout<<"\n哇,特等獎!你真厲害!"; 22 else if(abs(j-t)<=1) 23 cout<<"\n一等獎!很不錯呀!"; 24 else if(abs(j-t)<=2) 25 cout<<"\n二等獎!也可以啦..."; 26 else if(abs(j-t)<=3) 27 cout<<"\n三等獎!還要努力哦..."; 28 else 29 cout<<"\n真可惜!什么都沒有..."; 30 system("pause"); 31 return 0; 32 }
哈哈,我得了N個特等獎,獲得了N個高階的魔法卷軸。這是因為我發現這個程序通過獲取當前時間來生成隨機數的方法有一定的規律性,我只要估算好時間,就可以算出下一個數的大致范圍。
上面的程序中產生的隨機數,一般稱為偽隨機數,真隨機數的使用方法如下例所以(C++已默認包含time類的函數):
1 //真隨機數 2 #include <iostream> 3 using namespace std; 4 #define n 100 5 int a[101],i; 6 7 int main() 8 { 9 srand((unsigned)time(NULL)); //獲取隨機數種子,rand()產生0~32767之間的數 10 for(i=1;i<=n;i++) 11 a[i]=rand() % 100; 12 for(i=1;i<=n;i++) 13 cout<<a[i]<<' '; 14 getchar(); 15 return 0; 16 }
生成0~1之間的隨機整數:
1 //產生0~1之間的隨機數 2 #include <iostream> 3 using namespace std; 4 5 int main() 6 { 7 srand((unsigned)time(NULL)); 8 for(int i=1;i<=5000;i++) 9 cout<<rand()% (2)<<' '; 10 system("pause"); 11 return 0; 12 }
生成Low和hight范圍內的隨機整數:
1 //產生指定范圍內的隨機數 2 #include <iostream> 3 using namespace std; 4 5 int main() 6 { 7 int low,hight; 8 srand((unsigned)time(NULL)); 9 cin>>low>>hight; //輸入low,hight值,大小不得顛倒 10 for(int i=1;i<=5000;i++) 11 cout<<rand()%(hight-low+1)+low<<' '; 12 system("pause"); 13 return 0; 14 }
生成隨機字符串:
1 //產生指定長度的隨機字符串 2 #include <iostream> 3 using namespace std; 4 5 int main() 6 { 7 int i,n,m; //輸出n行m個字符的隨機字符串 8 string str; 9 cin>>n>>m; 10 srand((unsigned)time(NULL)); 11 for(i=1;i<=n;i++) 12 { 13 str=""; //清空字符串 14 for(int j=1;j<=m;j++) 15 { 16 int temp=rand()%2; //隨機決定輸出大寫或小寫字母 17 if (temp==0) 18 str+=(char)(rand()%(26)+1+64); //'A'=65,'Z'=90 19 else 20 str+=(char)(rand()%(26)+1+96); //'a'=97,'z'=122 21 } 22 cout<<str<<endl; 23 } 24 system("pause"); 25 return 0; 26 }
隨機數函數產生的數介于0~32767之間,因此,如果需要產生的隨機數大于32767,則還需要進一步的處理。想想看,怎么做?
在比賽中,有時寫好了一道題卻不知道正確與否,對此我們可以寫兩個不同算法的程序來“對拍”檢驗。例如針對某道題寫好的兩個程序分別為program1.cpp和program2.cpp,其中一個程序一般是保證絕對正確但運行效率很低的代碼(例如使用了窮舉算法),如下例所示:
1 //program1.cpp,此處僅為舉例,并不是低效算法 2 #include <iostream> 3 using namespace std; 4 5 int main() 6 { 7 freopen("in.txt","r",stdin); //從in.txt中讀取數據 8 freopen("out1.txt","w",stdout);//注意此處為out1.txt 9 int x; 10 cin>>x; 11 cout<<2*x<<endl; 12 }
第二個程序是優化后準備最終上交的程序,但不確定程序是否正確。
1 //program2.cpp,第二個程序,此處僅為舉例 2 #include <iostream> 3 using namespace std; 4 5 int main() 6 { 7 freopen("in.txt","r",stdin); //讀文件名相同,即in.txt 8 freopen("out2.txt","w",stdout);//注意此處為out2.txt 9 int x; 10 cin>>x; 11 cout<<x+x<<endl;//此處用了另一種方法計算結果 12 }
再根據題目要求寫出隨機生成測試數據的程序CreatRand.cpp:
1 //產生隨機數據 2 #include <iostream> 3 using namespace std; 4 5 int main() 6 { 7 freopen("in.txt","w",stdout); //產生的隨機數據寫入in.txt 8 srand((unsigned)time(NULL)); 9 cout<<rand()%1000<<endl;//隨機產生一個數 10 }
將此三個源程序均編譯成可執行文件,并放在同一文件夾下。在該文件夾下再用記事本等純文本編輯軟件編寫如下的“對拍”批處理文件例如test.bat。
1 @echo off 2 :start 3 CreatRand 4 5 program1 6 program2 7 fc out1.txt out2.txt>result.txt 8 :end 9 goto start
如圖3.8所示,雙擊運行批處理文件即可自動評測。

圖3.8
由于使用隨機數生成程序能自動產生無窮無盡的測試數據,所以批處理文件的第7行是把fc的結果寫入了result.txt文件中。運行時,一旦發現結果不一樣,就把錯誤結果記錄到result.txt文件中。
- C及C++程序設計(第4版)
- Learning ROS for Robotics Programming(Second Edition)
- Python量化投資指南:基礎、數據與實戰
- TypeScript Blueprints
- WebAssembly實戰
- CentOS 7 Linux Server Cookbook(Second Edition)
- 數據庫系統原理及MySQL應用教程
- MATLAB 2020 從入門到精通
- Java深入解析:透析Java本質的36個話題
- WordPress Plugin Development Cookbook(Second Edition)
- NGINX Cookbook
- Mastering openFrameworks:Creative Coding Demystified
- Mobile Device Exploitation Cookbook
- Laravel Application Development Blueprints
- Extending Unity with Editor Scripting