这两天为了帮老师统计第四轮学科评估中理学,工学,管理学,经济学中B以上的学科以及哪些非985,211的学校含有这些学科,需要大量的重复性操作,正好最近在学习C++中的类以及文件读取的操作,就用程序简化了一下操作,为统计工作节省了大量的时间,在此分享一下。
本文主要使用了类的构建以及txt文件的读取操作
- 问题描述
首先看一下EXCEL的数据信息的形式:
第一列是专业,二到五列是该专业在第四轮学科评估中评分为A+,A,A-,B+,B的学校。
这样的专业,理工管经这四个大类中总共有57个。
任务需要我将不同的学校中,评分在B以上的专业统计出来:
其中,每一个专业前需要加上该专业的代码。
起初我的方法是从数据EXCEL中查询学校名,然后一个个复制学科名到第二个EXCEL中,操作了一个以后发现实在是太麻烦了,首先复制专业的时候,得手动打上前面的代码号,其次每一次复制粘贴都很繁琐浪费大量时间,最后EXCEL的查询功能在面对一个单元格内有多行数据的查询时有时会出现小问题。
(最后编程输出的查询结果对比我自己查的第一个,我发现自己查的漏了几个,尚未找到原因,个人猜测是查询时出现的问题)
由于正好在学习C++,运用文件的读取操作实现数据的统计将大大简化工作量。
- 问题分析
将问题分为四步
-
类的构建
我们需要建立一个对象,该对象变量包含:专业名称,该专业内学校个数,以及该专业的学校名称
-
数据预处理
需要建立txt文件是一个是包含所有专业名称的txt文件如下:
和另一个文件夹,文件夹内是不同学科所含的文件
其中每一个文件是该专业所含的学校
-
文件的输入
读入文件夹里的所有数据,建立57个学科对象组
-
数据的查找
建立函数,通过关键字查找每一个对象内是否包含该学校,若是则返回该对象的学科名
-问题解决
- 头文件
#include <iostream>
#include <fstream>//文件读取需要的类
#include <string>
using namespace std;
- 学科类的构建
class Subject
{
private:
string sub_name;//该学科学科名
int sub_number;//该学科内学校的个数
string school[75];//该学科包含的学校数组
public:
Subject(){};//默认的构造函数
void set(string address, string a);//设置函数
void show();//显示学科及内所有学校
string findschool(string);//查找该学科内是否有该学校
};
- 对象初始化
void Subject::set(string address, string a)
{
ifstream in(address);
int n = 0;
if (!in)
{
cout << "不可打开的文件" << endl;
}
else
{
sub_name = a;
n = 0;
while (getline(in, school[n])) //将txt文件按行读入string字符串组
{
n++;//统计该学科有多少学校
}
}
sub_number = n;
in.close();
}
- 显示对象
void Subject::show()//显示该学科的学校
{
cout << sub_name << endl;
int i = 0, n = sub_number;
while (n)
{
cout << school[i] << endl;
i++; n--;
}
}
- 通过字符串查找该学科类是否包含该学校
string Subject::findschool(string a)//通过字符串a查找学科名
{
for (int i = 0; i < sub_number; i++)
{
if (a == school[i])
return sub_name + ',';
}
return "";
}
- 主程序
int main()
{
string sub[60], temp;//用于存放学科名
Subject a[60];//用于存放Subject类
int n = 0;//总共有n个学科
/*--------------------------------------------------*/
ifstream in("D:\\理工管经所有学科及代码.txt");
// 提前准备一个包含所有学科名及代码的txt,数据预处理的第一个文件
while (getline(in, sub[n])) //将所有的学科名通过文件存在变量sub里
{
n++;
}
in.close();
/*--------------------------------------------------*/
for (int i = 0; i < n; i++)//将所有的学科及学科所含学校存在a中
{
temp = "D:\\B以上专业学校\\" + sub[i] + ".txt";//读取该文件夹里的所有学科的信息
a[i].set(temp, sub[i]);
}
string name;//输入要查找的学科
cin >> name;
while (1)
{
for (int i = 0; i < n; i++)
{
temp = a[i].findschool(name);
cout << temp;
}
cout << endl << endl;
cin >> name;
}
return 0;
}
-运行结果
至此节约了大量的重复工作。
PS:还有很多可以改进的地方,如数据预处理的过程也可以通过程序处理,最后的统计结果可以输出至一个txt文件中等。
为了得到第一个txt文件,其实是通过一个程序将第二个文件夹内的所有文件的文件名输出至一个txt,详情见:https://www.cnblogs.com/tgyf/p/3839894.html
借鉴了该作者的方法,在此不再赘述。