輸入:N(整數)
輸入:數據文件A.txt,不超過6條記錄,字符串長度不超過15個字節
文件格式如下:
字符串\t數字\n
說明:
每行爲1條記錄;字符串中不含有\t。
數字描述的是該字符串的出現概率,小於等於100的整數。
多條記錄的出現概率之和爲100,如果A.txt不滿足該條件,程序則退出;
如果文件格式錯誤,程序也退出。
要求:
編寫一個程序,輸入爲N(正整數),讀入文件A.txt,按照字符串出現概率隨機地輸出字符串,輸出N條記錄
例如:
輸入文件A.txt
abc\t20
a\t30
de\t50
輸入爲:10
即 abc有20%的概率輸出,a有30%的概率輸出,de有50%的概率輸出,輸出10條記錄
以下爲一次輸出的結果,多次輸出的結果可能不相同。
abc
a
de
de
abc
de
a
de
a
de
題目解析:這個題目其實考察了很多,隨機數生成的問題,文件訪問的問題,二者中有很多小細節容易讓我們忽略的。但是最巧妙的考點是如何按照指定的概率輸出。
爲此我指定了一個數組number[10],number[i]用於存放字符串i的輸出此時,即使用輸入的對應頻率除以10,就可到了number[i]。我的實現中沒有考慮全部的情況,只處理輸入頻率爲10的整數倍。做這種題目的時候,要留心,處理輸入不合法,還有總頻率和不等於100的情況。
核心步驟是:
1、產生一個隨機數 rad;
2、另rad=rad/array_length;array_length爲輸入的字符串的個數
3、看產number[rad]的值,如果>0,則輸出第rad字符串,如果=0.則 rad=(rad+1)%array_length。訪問下一個字符串,如果還是爲0的話,則繼續順序訪問。
4、循環執行步驟3共n次,就得到符合的結果了
程序如下:
#include<cstring>
#include<iostream>
#include <time.h>
#include <fstream>
using namespace std;
int main()
{
int n;//表示一共輸出多少個數,本例實現中只針對n爲10的整數倍的數
cin >> n;
char buffer[256];
ifstream readfile("random.txt");
if(!readfile){
cout << "Unable to open readfile";
exit(1); // terminate with error
}
char array[10][10];//存放輸入的字符串組合
double number[10]={0,0,0,0,0,0,0,0,0,0};//存放對應字符串的頻率
char a_buf[30];//臨時緩衝,存放輸入字符串
int b; //臨時緩衝,存放輸入對應字符串的頻率,
int i=0; //用於統計一共多少個字符串
int sum=0;//用於統計輸入的頻率,查看最後的頻率和是否爲1000
while (! readfile.eof() )
{
readfile.getline (buffer,10);
sscanf(buffer,"%s %d",&a_buf,&b);
if(a_buf[0] =='@'|| b<=0)
{ //輸入不合法
// cout <<" The input is error1 "<<endl;
return 0;
}
number[i]=(b/10)*(n/10);//計算每個對應字符串最終輸出中輸出多少個
sum+=b;//統計頻率和
// cout << number[i]<<" This is number[i]"<<endl;
int len=strlen(a_buf);
// cout << "len is "<<len<<endl;
for(int j=0; j<len;j++)
array[i][j]=a_buf[j];
array[i][j]='\0';//字符串結尾處理
i++;
a_buf[0]='@';//緩衝區更新爲無實際意義的字符
b=-1;
}
readfile.close();
int array_length=i;//記錄一共有多少行輸入
if(sum!=100){//總頻率和不爲100,則錯誤,返回
cout << sum<<endl;
cout << "The input is error 2:"<<endl;
return 0;
}
cout <<"The random result is: "<<endl;
srand( (unsigned)time( NULL ) );//產生隨機數
for(i=0; i<n;i++){
int rad = rand();
rad=rad%array_length;//讓隨機數控制在0~array_length之內
while(number[rad]==0)
{
rad=((rad+1)%array_length);//如果對應的number次數爲0,表示該字符串需要輸出的次數已經全部輸出,換到下一個字符串
}
int length = strlen(array[rad]);
for(int j=0; j<length;j++)//字符串輸出
{
cout << array[rad][j];
}
cout <<endl;
number[rad]--;//輸出字符串的number次數減1
}
return 1;
}
測試數據:
文件裏面
a 50
bb 10
ccc 20
dddd 20
終端輸入10.
第一次隨機結果爲:
The random result is:
a
dddd
ccc
ccc
ccc
dddd
dddd
ccc
ccc
bb
Press any key to continue
第二次隨機結果爲:
10
The random result is:
a
a
a
ccc
dddd
bb
dddd
ccc
a
a
Press any key to continue