官术网_书友最值得收藏!

產生隨機數據

有些測試數據必須手工制作,以防止某些特例的出現,但是除此之外的多數測試數據,如果能寫一個程序自動產生該有多好!這顯然需要隨機數函數的幫忙了。

【例題描述】 趣味搖獎機

魔法學院舉行游園活動,為了烘托節日氣氛,決定在活動中設一個如圖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文件中。

主站蜘蛛池模板: 临安市| 原阳县| 九江县| 深州市| 柏乡县| 墨竹工卡县| 油尖旺区| 鹤岗市| 西乌珠穆沁旗| 德昌县| 兴城市| 武威市| 大兴区| 和田市| 集安市| 开封市| 微博| 济源市| 曲麻莱县| 南澳县| 华池县| 遵义市| 涿鹿县| 阿克| 来安县| 婺源县| 许昌市| 泸西县| 南召县| 滁州市| 宿迁市| 蒲江县| 孝义市| 定边县| 子洲县| 仁布县| 平武县| 沂水县| 炉霍县| 临颍县| 泰来县|