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