百度的一道有關隨機數按照指定頻率輸出的題


輸入: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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章