【苏大C++期中模拟三】题目与代码

目录

一、题目

二、代码 


写在前面:这道题需要注意的就是最后一个数值转换,记得转成double呀!

一、题目

ppp考试说明

  1. 考试时间:合计2小时。选择题部分30分钟交卷,允许提前交卷。
  2. 考试过程中,不能连接未经指定网站或服务器。
  3. 闭卷考试部分,不能查阅任何类型的参考资料。
  4. 开卷考试部分,可以查阅纸质文档,不能查阅任何类型的电子文档。
  5. 考试过程中,不得使用任何形式的电子存储设备,不可使用手机。
  6. 违反上述2-5条者,视为考试作弊。

选择题答题方式(20分,闭卷,严禁使用vs编程环境进行尝试

  1. 打开浏览器,在地址栏中输入http://192.168.151.175:81,点击相应链接进入登录页面。
  2. 按要求输入两遍自己的学号。
  3. 点击“登录”按钮即可进入答题页面。如考试尚未开始,系统会进入等待页面并倒计时。考试开始时间到,系统会自动进入答题页面。
  4. 在页面左侧选择题号,页面右侧即会显示相应的题目。考生只需点击选择相应的选项。
  5. 答题过程中如关闭浏览器或出现系统故障导致计算机重新启动,系统不会丢失之前已经完成的题目的答案。考生可以打开浏览器重新登录并继续考试。
  6. 答题完成后,点击“交卷”按钮即可完成交卷。交卷后不能再次登录系统继续考试。
  7. 考试结束时间到,系统会自动收卷。

编程题提交方式(80分,开卷)

  1. 提交前务必关闭vs2005vs2008或vs2010编程环境。
  2. 所有源程序内容必须仅包含在一个源程序文件(CPP文件)中。
  3. 在浏览器的地址栏中输入http://192.168.151.175:81,点击相应链接进入提交页面。
  4. 按要求输入两遍自己的学号。
  5. 点击“选择文件”按钮,选择自己的源程序文件。点击“提交”按钮提交。
  6. 如提交成功,系统会显示相关信息。如果提交不成功,请重复步骤16-18。
  7. 提交成功后,可点击“查看内容”按钮检查提交的内容。


按以下要求编写程序

题目说明

请各位考生课程信息发布网站下载数据文件data.txt,然后将该数据文件手动保存D盘根目录下。该文件中的数据以文本形式存储,每行包含3列数据,格式如下:A列和B列都是单词,C列是同一行A列和B列中单词共同出现的次数,列之间用tab隔开。文件总行数在千行以上,A列或B列的单词可能重复,如下面例子所示:

A          B          C

打         电话        2

喝         啤酒        3

打         人          5

吃         苹果        6

打         电话        1

                  

上面第一行表示电话两个单词在文档1中共同出现了2次,最后一行表示这两个单词在文档2中一起出现了1次,诸如此类。

定义结构体unit和unita,用来存储如下数据:

typedef struct {

string a; //存储A列的单词

string b; //存储B列的单词

int cab; //存储单词a和单词b在所有文档中共同出现次数的总和

} unit;

typedef struct{

string a; //A列的单词

int ca; //单词a在所有文档中出现的次数总和

}unita;

比如在上面的示例中,“打”和“电话”共同出现的次数总和为2+1=3次,“打”单独出现的次数总和为2+5+1=8次。

请按要求依次完成如下操作:

  1. 编写一个函数read_data,读取data.txt文件中的所有数据,并将它们存放在一个unit的向量vunit中,要求向量里所有单元的a和b都不重复,对重复的a和b,将它们共同出现次数累加到c中。(注意:向量不同单元中的单个a或单个b可以相同,但不允许a和b同时相同
  2. 编写一个函数cal_counts,以引用方式将vunit传递给该函数,并计算A列单词在所有文档中出现的次数,将计算结果保存在另一个向量vector<unita> vunita中。
  3. 编写一个排序函数sort_units,将向量vunit中的元素按照出现次数cab由高到低排序。
  4. 编写一个重载的排序函数sort_units,将向量vunita中的元素按照出现次数ca由高到低排序。
  5. 编写一个函数print_top_units,将排序后的向量vunita中的前20个元素按下面显示格式输出到屏幕上:

显式a,显示宽度为10,不足的以“S”补齐,向右对齐

显式ca,显式宽度5,不足的以“$”补齐,向右对齐

   $$$$8

   $$$$6

  1. 编写一个条件概率计算函数cal_probs,以引用方式将vunit和vunita传递给该函数,计算一个概率表,并将该概率表输出到文件prob.txt中(同样存放在d盘根目录下),文件每一行格式为:A列单词a ||| B列单词b||| p(b|a),即给定A列一个单词的情况下,B列某个单词出现的概率p(b|a)= cab/ca,如按照上面的例子p(电话|打)=3/8=0.375。按照vunit中元素的顺序将以上概率输出到文件prob.txt中。(注意,只需计算vunit中出现的A列单词和B列单词对的概率,vunit中没有出现的A、B列单词组合无需考虑)
  2. main函数如下:

int main() {

string rfn = "d:\\data.txt";

string wfn ="d:\\prob.txt";

vector<unit> vunit;

vector<unita> vunita;

    

read_data(rfn, vunit);

cal_counts(vunit, vunita);

sort_units(vunit);

sort_units(vunita);

    cout << "A列单词出现次数前20" << endl;

    print_top_units(vunita);

cout <<"计算条件概率并输出到" <<wfn<< endl;

cal_probs(vunit, vunita, wfn);

   

    return 0;

}

注意: 不允许修改main函数,每修改一处,扣3分;

评分标准

(编程题满分为80分)

大项

子项

评分项

应得分

实得分

70

结果(70分)

编译子项5分

文件读取函数read_data

15

次数统计函数cal_counts

15

两个向量排序函数sort_units

共10分,每个5分

向量打印函数print_top_units

10

概率计算和输出函数cal_probs

15

上述各项都不得分

编译子项

本项不得分

程序运行出现异常

-10

程序死循环

-10

修改main函数

-3(每处修改)

编译(5分)

编译连接均通过(无warning)

5

编译连接均通过(有warning)

4

编译通过、连接不通过

3

编译、连接均不通过

0

10分

缩进对齐(4分)

正确运用缩进对齐规则

4

有缩进对齐但不完全符合要求

2

没有使用缩进对齐规则

0

注释(3分)

有详细且正确的注释

3

有注释,但不够详细

2

完全没有注释

0

变量命名(3分)

变量命名有规则

3

变量命名有规则、但规则使用不一致

2

变量命名无规则

0

总分(满分80分)

二、代码 

#include <iostream>
#include<vector>
#include<string>
#include<fstream>
#include<algorithm>
#include<iomanip>
using namespace std;
typedef struct {
string a; //存储A列的单词
string b; //存储B列的单词
int cab; //存储单词a和单词b在所有文档中共同出现次数的总和
} unit;

typedef struct{
	string a; //A列的单词
	int ca; //单词a在所有文档中出现的次数总和
}unita;

void read_data(string path,vector<unit>&t){
    ifstream ifile(path);
    while(!ifile.eof()){
        unit u;
        if(ifile>>u.a>>u.b>>u.cab){
            int i;
            for(i=0;i<t.size();i++){
                if(t[i].a==u.a && t[i].b==u.b){
                    t[i].cab+=u.cab;
                    break;
                }
            }
            if(i==t.size()){
                t.push_back(u);
            }
        }
    }
    ifile.close();
}

void cal_counts(const vector<unit>&t,vector<unita>&ta){
    for(int i=0;i<t.size();i++){
        int j;
        for(j=0;j<ta.size();j++){
            if(ta[j].a==t[i].a){
                ta[j].ca+=t[i].cab;
                break;
            }
        }
        if(j==ta.size()){
            unita u;
            u.a=t[i].a;
            u.ca=t[i].cab;
            ta.push_back(u);
        }
    }
}

int cmp1(unit a,unit b){
    return a.cab>b.cab;
}
void sort_units(vector<unit>&t){
    //将向量vunit中的元素按照出现次数cab由高到低排序
    sort(t.begin(),t.end(),cmp1);
}

int cmp2(unita a,unita b){
    //将向量vunita中的元素按照出现次数ca由高到低排序。
    return a.ca>b.ca;
}
void sort_units(vector<unita>&ta){
    //将向量vunit中的元素按照出现次数cab由高到低排序
    sort(ta.begin(),ta.end(),cmp2);
}

void print_top_units(const vector<unita>&ta){
    /*
    5、编写一个函数print_top_units,
    将排序后的向量vunita中的前20个元素按下面显示格式输出到屏幕上:
显式a,显示宽度为10,不足的以“S”补齐,向右对齐	
显式ca,显式宽度5,不足的以“$”补齐,向右对齐
打	   $$$$8
吃	   $$$$6
    */
    for(int i=0;i<20;i++){
        cout<<right<<setfill('S')<<setw(10)<<ta[i].a;
        cout<<right<<setfill('$')<<setw(5)<<ta[i].ca<<endl;
    }
}

void cal_probs(const vector<unit>&t, const vector<unita>&ta, string path){
    /*
    A列单词a ||| B列单词b||| p(b|a),
    即给定A列一个单词的情况下,B列某个单词出现的概率p(b|a)= cab/ca,
    如按照上面的例子p(电话|打)=3/8=0.375。
    按照vunit中元素的顺序将以上概率输出到文件prob.txt中。
    (注意,只需计算vunit中出现的A列单词和B列单词对的概率,
    vunit中没有出现的A、B列单词组合无需考虑)
    */
    ofstream ofile(path);
    for(int i=0;i<t.size();i++){
        double pba;
        for(int j=0;j<ta.size();j++){
            if(ta[j].a==t[i].a){
                pba=(double)t[i].cab/(double)ta[j].ca;
                break;
            }
        }
        ofile<<t[i].a<<"|||"<<t[i].b<<"|||"<<pba<<endl;
    }
    ofile.close();
}
   


int main() {
string rfn = "d:\\data.txt";
string wfn ="d:\\prob.txt";
vector<unit> vunit;
vector<unita> vunita;
    
read_data(rfn, vunit);
cal_counts(vunit, vunita);
sort_units(vunit);
sort_units(vunita);
    cout << "A列单词出现次数前20:" << endl;
    print_top_units(vunita);
cout <<"计算条件概率并输出到:" <<wfn<< endl;
cal_probs(vunit, vunita, wfn);
   
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值