说明:CSDN不允许上传附件,所以我不会把题目放上来。写这个博客的主要目的是为了让同校的学弟学妹们复习的时候有一个参考。当然,都是我自己写的,并不保证答案完全正确对本次考试,会简单的做一个解析。其他三次小练习,仅附上代码。有需要交流讨论、想要题目信息的同学,可以私信我。
附上我的代码。
你可能出现的问题有:
0.没有考虑钳工等级的合理区间,我也扣了4分。在代码中已经做了修改。这也是绝大部分96分同学的扣分点。
1.对于继承和派生的构造函数不知道怎么写。
2.不知道该怎么删除不合理的数据。(从后往前删的办法应该从第一次考试就考了,还不会的同学有点不应该了。)
3.不知道如何查找字符串。(你当然可以用很方便的函数来完成转化大小写和查找的效果,也可以自己写。转化大小写我是手写的,查找我用了一个函数,因为自己写会比较麻烦。但是绝对不难。)
4.排序问题。有人会写成两个cmp函数,更麻烦一点。实际上一个cmp就可以了。
5.输出的时候,不会调用父类的“<<”。子类如何调用父类的友元函数?应该使用强制类型转换。这个问题在考前小练习1中也有所涉及。
#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
class CWorker
{
private:
int m_ID; //工号
string m_Name; //姓名
int m_Sex; //性别 0代表女性 1代表男性
int m_Age; //年龄
public:
CWorker(int ID, string Name, int Sex, int Age)
{
if (Sex<0 || Sex>1)
{
cout<<"性别初始值"<<Sex<<"不符合要求!"<<endl;
exit(0);
}
if (Age<=0 )
{
cout<<"年龄初始值"<<Age<<"不符合要求!"<<endl;
exit(0);
}
m_ID=ID;
m_Name=Name;
m_Sex=Sex;
m_Age=Age;
}
string GetName()const
{
return m_Name;
}
int GetSex()const
{
return m_Sex;
}
int GetAge()const
{
return m_Age;
}
friend ostream& operator<<(ostream& Out, const CWorker& Obj)
{
Out<<right<<setw(5)<<Obj.m_ID;
Out<<right<<setw(10)<<Obj.m_Name;
Out<<right<<setw(5)<<Obj.m_Sex;
Out<<right<<setw(6)<<Obj.m_Age;
return Out;
}
};
class CBenchWorker: public CWorker
{
private:
int m_Grade;//钳工级别 1-5 最大为5级
public:
CBenchWorker(int ID = 0, string Name = "No Name", int Sex = 1, int Age = 18, int Grade = 1):CWorker(ID, Name, Sex, Age){
if(Grade < 1 || Grade > 5){
cout << "钳工级别不符合要求!" << endl;
exit(1);
}
m_Grade = Grade;//构造函数
}
int GetGrade()//获取钳工级别
{
return m_Grade;
}
CBenchWorker &operator++()//前自增
{
m_Grade += 1;//级别加一
if(Grade < 1 || Grade > 5){
cout << "钳工级别不符合要求!" << endl;
m_Grade -= 1;
exit(1);
}
return *this;
}
friend ostream& operator<< (ostream& Out, const CBenchWorker& Obj);//输出流运算符
};
ostream& operator<< (ostream& Out, const CBenchWorker& Obj)
{
Out << (CWorker)Obj << setw(5) << right << Obj.m_Grade;
return Out;
}
int ReadData(string rfn, vector<CBenchWorker> &myVect)//读取文件
{
ifstream infile(rfn, ios::in);
if(!infile)//判断打开文件是否成功
{
cout << "打开文件失败" << endl;
return 0;
}
int ID, Sex, Age, Grade;
string Name;
while(infile >> ID >> Name >> Sex >> Age >> Grade){
CBenchWorker temp(ID, Name, Sex, Age, Grade);//初始化工人信息
myVect.push_back(temp);//添加至vector
}
infile.close();//关闭文件
return 1;
}
void DisplayData(vector<CBenchWorker> myVect){//展示信息
for(int i = 0; i < myVect.size(); i++)//输出每条信息
cout << myVect[i] << endl;
}
void InecData(vector<CBenchWorker> &myVect){//自增函数
for(int i = 0; i < myVect.size(); i++){//每个工人执行前自增操作
++myVect[i];
}
}
int DelData(vector<CBenchWorker> &myVect, int X, int Y){//删除函数
int cnt = 0;//计数变量
for(int i = myVect.size()-1; i >= 0; i--){
if(myVect[i].GetAge() >= X && myVect[i].GetGrade() <= Y){//判断工人工龄大于X,级别小于Y
cnt++;
myVect.erase(myVect.begin() + i);//从后往前删除
}
}
return cnt;//返回删除个数
}
int DelData(vector<CBenchWorker> &myVect, string X){//删除函数2
int cnt = 0;//技术变量
for(int i = 0; i < X.size(); i++){
if(X[i] >= 'A' && X[i] <= 'Z')
X[i] += 32;//全部转化为小写
}
for(int i = myVect.size()-1; i >= 0; i--){
string Y = myVect[i].GetName();
for(int j = 0; j < Y.size(); j++){
if(Y[j] >= 'A' && Y[j] <= 'Z')
Y[j] += 32;//全部转化为小写,由于新定义了string,不会改变原来vector内的name
}
if(Y.find(X) != Y.npos){
myVect.erase(myVect.begin() + i);//从后往前删除并且计数
cnt++;
}
}
return cnt;//返回删除个数
}
bool cmp(CBenchWorker A, CBenchWorker B)
{
if(A.GetSex() == B.GetSex()){//判断性别是否相等
if(A.GetSex() == 0)//都是女性的情况下
return A.GetGrade() > B.GetGrade();//级别降序
else
return A.GetGrade() < B.GetGrade();//级别升序
}
return A.GetSex() < B.GetSex();//女士优先
}
void SortData(vector<CBenchWorker> &myVect){//排序函数
sort(myVect.begin(),myVect.end(),cmp);
}
int WriteData(string wfn, vector<CBenchWorker> myVect){//写入文件
ofstream outfile(wfn,ios::out);
if(!outfile)//判断打开文件是否成功
{
cout << "打开文件失败" << endl;
return 0;
}
for(int i = 0; i < myVect.size(); i++){//写入数据
outfile << myVect[i] << endl;
}
outfile.close();//关闭文件
return 1;
}
int main()
{
vector<CBenchWorker> a;
int c;
if (ReadData("d:\\workers.txt", a)==0)
return -1;
cout<<"文件读取后一共有 "<<a.size()<<" 条钳工数据:"<<endl;
DisplayData(a);
InecData(a);
c=DelData(a,55,2); //第2个参数为年龄,第3个参数为等级
cout<<endl<<"第1次删除了"<<c<<"个钳工数据"<<endl;
c=DelData(a,"Tom");
cout<<endl<<"第2次删除了"<<c<<"个钳工数据"<<endl;
SortData(a);
cout<<endl<<"上述流程结束后一共有 "<<a.size()<<" 条钳工数据:"<<endl;
DisplayData(a);
if (WriteData("d:\\res.txt",a)==0)
return -1;
cout<<endl<<"文件保存成功"<<endl<<endl;
}
考前小练习1:
#include<iostream>
#include<vector>
#include<iomanip>
#include<fstream>
#include<cmath>
#include<algorithm>
using namespace std;
class CPU{
private:
double m_MainFreq; //主频,单位GHz
int m_CoreNum; //核心数
double m_Power; //功率,单位:W
public:
CPU(double MainFreq, int CoreNum, double Power);
double GetMainFreq(void)const; //获取主频
CPU& operator++(); //前自增,主频加0.1,核心数加2,功率加1.0
CPU operator++(int); //后自增,规则同上
friend ostream& operator<<(ostream& Out, const CPU& Obj); //输出CPU的参数,
//主频占6列,小数部分保留2位,左对齐
//核心数占3列,左对齐
//功率占6列,小数部分保留1位,左对齐
};
//CPU类的构造函数
CPU::CPU(double MainFreq, int CoreNum, double Power){
m_MainFreq=MainFreq;
m_CoreNum=CoreNum;
m_Power=Power;
}
//CPU类的GetMainFreq ()成员函数
double CPU::GetMainFreq(void)const{
return m_MainFreq;
}
//CPU类的前++运算符重载成员函数
CPU& CPU::operator++(){
m_MainFreq+=0.1;
m_CoreNum+=2;
m_Power+=1.0;
return *this;
}
//CPU类的后++运算符重载成员函数
CPU CPU::operator++(int){
CPU temp(*this);
++(*this);
return temp;
}
//CPU类的输出运算符重载函数
ostream& operator<<(ostream& Out, const CPU& Obj){
Out<<left<<setw(6)<<fixed<<setprecision(2)<<Obj.m_MainFreq<<
left<<setw(3)<<Obj.m_CoreNum<<
left<<setw(6)<<fixed<<setprecision(1)<<Obj.m_Power;
return Out;
}
class Computer{
private:
CPU m_CPU;
int m_Memory; //内存容量,单位:G
int m_HD; //硬盘容量,单位:G
public:
Computer(double CPU_MainFreq, int CPU_CoreNum, double CPU_Power, int Memory, int HD);
CPU GetCPU(void)const; //获取CPU数据
double GetMemory(void)const; //获取内存容量
Computer& operator++(); //前自增,CPU部分自增规则同CPU类,内存扩大4G,硬盘扩大128G
Computer operator++(int); //后自增,规则同上
friend ostream& operator<<(ostream& Out, const Computer& Obj);
//CPU部分数据的输出规则与CPU类中定义相同
//内存容量占6列,左对齐
//硬盘容量占8列,左对齐
};
//Computer类的构造函数
Computer::Computer(double CPU_MainFreq, int CPU_CoreNum, double CPU_Power, int Memory, int HD):m_CPU(CPU_MainFreq,CPU_CoreNum,CPU_Power){
m_Memory=Memory;
m_HD=HD;
}
//Computer类的GetCPU()成员函数
CPU Computer::GetCPU(void)const{
return m_CPU;
}
//Computer类的GetMemory()成员函数
double Computer::GetMemory(void)const{
return m_Memory;
}
//Computer类的前++运算符重载成员函数
Computer& Computer::operator++(){
++m_CPU;
m_Memory+=4;
m_HD+=128;
return *this;
}
//Computer类的后++运算符重载成员函数
Computer Computer::operator++(int){
Computer temp(*this);
++(*this);
return temp;
}
//Computer类输出运算符重载函数
ostream& operator<<(ostream& Out, const Computer& Obj){
Out<<Obj.m_CPU<<
left<<setw(6)<<Obj.m_Memory<<
left<<setw(8)<<Obj.m_HD;
return Out;
}
class IPC:public Computer{
private:
int m_ProtectGrade; //防护等级
static int m_Counts; //工控机数量
public:
IPC(double CPU_MainFreq=3.7, int CPU_CoreNum=6, double CPU_Power=95.0, int Memory=16, int HD=512, int ProtectGrade=65);
IPC(const IPC& Obj);
double GetProtectGrade(void)const; //获取防护等级
static int GetCounts(void); //获取当前工控机数量
IPC& operator++(); //前自增,Computer数据自增规则同上,防护等级加1
IPC operator++(int); //后自增,规则同上
friend ostream& operator<<(ostream& Out, const IPC& Obj);
//Computer部分数据的输出规则与Computer类中定义相同
//防护等级占5列,左对齐
~IPC();
};
//IPC类的有参构造函数
IPC::IPC(double CPU_MainFreq, int CPU_CoreNum, double CPU_Power, int Memory, int HD, int ProtectGrade):Computer(CPU_MainFreq,CPU_CoreNum,CPU_Power,Memory,HD){
m_ProtectGrade=ProtectGrade;
m_Counts++;
}
//IPC类的复制构造函数
IPC::IPC(const IPC& Obj):Computer(Obj){
m_ProtectGrade=Obj.m_ProtectGrade;
m_Counts++;
}
//IPC类的GetProtectGrade()成员函数
double IPC::GetProtectGrade(void)const{
return m_ProtectGrade;
}
//IPC类的GetCounts()成员函数
int IPC::GetCounts(void){
return m_Counts;
}
//IPC类的前++运算符重载成员函数
IPC& IPC::operator++(){
Computer::operator++();
m_ProtectGrade++;
return *this;
}
//IPC类的后++运算符重载成员函数
IPC IPC::operator++(int){
IPC temp(*this);
// m_Counts--;
++(*this);
return temp;
}
IPC::~IPC(){
m_Counts--;
}
//IPC类的输出运算符重载函数
ostream& operator<<(ostream& Out, const IPC& Obj){
// cout << 1 << endl;
Out << static_cast<Computer>(Obj)<<left<<setw(6)<<Obj.m_ProtectGrade;
// cout << 1 << endl;
return Out;
}
//初始化
int IPC::m_Counts=0;
//函数ReadIPCFile,从D盘根目录下的文本文件source.txt中读取数量未知个工控机数据,构成一个IPC类型的向量A
void ReadIPCFile(string filename, vector<IPC>& A){
ifstream data("d:\\source.txt",ios::in);
if(!data){
cout<<"ERROR!"<<endl;//打开失败就退出
return;
}
double main,power;
int core,memory,hd,protect;
while(data>>main>>core>>power>>memory>>hd>>protect){
IPC temp(main,core,power,memory,hd,protect);
A.push_back(temp);
}
data.close();
return;
}
//函数SortIPC,对上述A向量进行增序排序,排序条件定义如下:
//a) CPU主频
//b) 防护等级
//注意:上述排序条件是有顺序的,必须按照"a条件-b条件"的顺序来进行处理
bool judge(IPC a,IPC b){
if((a.GetCPU()).GetMainFreq()<(b.GetCPU()).GetMainFreq())return true;
else if(a.GetProtectGrade()<b.GetProtectGrade())return true;
else return false;
}
void SortIPC(vector<IPC>& A){
sort(A.begin(),A.end(),judge);
}
//函数IncreaseIPC,对上述经过排序处理后的A向量中内存容量小于等于4G的工控机数据进行前自增处理,
//自增处理后的工控机数据必须要仍然保存在A向量中原数据位置处
void IncreaseIPC(vector<IPC>& A){
for(vector<IPC>::iterator it=A.begin();it!=A.end();it++){
if((*it).GetMemory()<=4){
++(*it);
}
}
}
//将经过上述处理后的A向量中所有工控机数据保存在D盘根目录下的文本文件res.txt中
void OutputIPCFile(vector<IPC>&A,string filename){
ofstream file(filename, ios::out);
for(vector<IPC>::iterator it = A.begin(); it != A.end(); it++) {
file <<*it << endl;
}
file.close();
}
int main()
{
vector<IPC> A;
ReadIPCFile("d:\\source.txt", A);
cout<<"当前工控机台数: "<<IPC::GetCounts()<<endl;
SortIPC(A);
IncreaseIPC(A);
cout<<"当前工控机台数: "<<IPC::GetCounts()<<endl;
OutputIPCFile(A,"d:\\res.txt");
IPC t1;
cout<<t1<<endl;
cout<<t1++<<endl;
cout<<t1<<endl;
cout<<"当前工控机台数"<<IPC::GetCounts()<<endl;
IPC t2(t1);
cout<<t2<<endl;
cout<<"当前工控机台数"<<IPC::GetCounts()<<endl;
}
考前小练习2:
#include<bits/stdc++.h>
using namespace std;
class CGoods
{
private:
int m_num; //商品编号
string m_name; //商品名称
float m_price; //商品价格
public:
CGoods (int, const string&, float);
friend ostream& operator<<(ostream&, const CGoods&);
//商品名称、商品编号和商品价格的显示格式都要求为占10列、右对齐
};
CGoods::CGoods(int num, const string& name, float price)
{
m_num = num;
m_name = name;
m_price = price;
}
ostream& operator<<(ostream& out, const CGoods& t){
out << setw(10) << right << t.m_num << setw(10) << t.m_name << setw(10) << t.m_price;
return out;
}
class CRouter : public CGoods
{
private:
float m_rate;
int m_portNum;
public:
CRouter(int num = 1, const string& name = "M8", float price = 100.0, float rate = 2.4,int portNum = 8):CGoods(num,name,price){
m_rate = rate;
m_portNum = portNum;
}
int GetChannels()
{
return this->m_portNum;
}
float GetFrequency()
{
return this->m_rate;
}
CRouter &operator ++()
{
m_portNum++;
return *this;
}
CRouter operator++(int)
{
CRouter temp(*this);
m_portNum++;
return temp;
}
friend ostream &operator<<(ostream &out, const CRouter& t);
};
ostream &operator<<(ostream &out, const CRouter& t){
out << (CGoods)t << setw(10) << t.m_rate << setw(10) << t.m_portNum;
return out;
}
void ReadData(vector<CRouter> &s,string rfn)
{
ifstream infile(rfn,ios::in);
if(!infile){
cout << "error" << endl;
exit(1);
}
int num,portNum;
string name;
float price,rate;
while(infile>>num>>name>>price>>rate>>portNum){
CRouter temp(num,name,price,rate,portNum);
s.push_back(temp);
}
return;
}
void DisplayData(vector<CRouter> s){
for(int i = 0; i < s.size(); i++){
cout << s[i] << endl;
}
}
CRouter FindMax(vector<CRouter> s){
int MaxNum = 0;
float MAX = 0;
for(int i = 0; i < s.size(); i++)
{
if(s[i].GetChannels() * s[i].GetFrequency() >= MAX){
MaxNum = i;
MAX = s[i].GetChannels() * s[i].GetFrequency();
}
}
return s[MaxNum];
}
int main()
{
vector<CRouter> s;
ReadData(s,"D:\\Data.txt");
cout<<"读取完成后的向量为"<<endl;
DisplayData(s);
CRouter t;
cout<<endl<<"路由器对象的初始值为"<<endl<<t<<endl;
t=FindMax(s);
cout<<endl<<"乘积最大的向量元素为"<<endl<<t<<endl;
cout<<endl<<"乘积最大的向量元素进行自增运算结果分别如下:"<<endl;
cout<<t++<<endl;
cout<<t<<endl;
cout<<++t<<endl;
cout<<t<<endl;
}
考前小练习3:
#include<bits/stdc++.h>
using namespace std;
class Time
{
protected:
int m_hour, m_minute, m_second; //m_hour值可正可负,详见说明。
public:
Time(int hour = 0, int minute = 0, int second = 0){
m_hour = hour;
if(minute <= 59 && minute >= 0)
m_minute = minute;
else
m_minute = 0;
if(second <= 59 && second >= 0)
m_second = second;
else
m_second = 0;
} //构造函数
void set(int hour = 0, int minute = 0, int second = 0){
m_hour = hour;
if(minute <= 59 && minute >= 0)
m_minute = minute;
else
m_minute = 0;
if(second <= 59 && second >= 0)
m_second = second;
else
m_second = 0;
} //设置时间
Time operator - (const Time & tm){
int sum1 = m_hour * 3600 + m_minute * 60 + m_second;
int sum2 = tm.m_hour * 3600 + tm.m_minute * 60 + tm.m_second;
int ans = max(sum1,sum2) - min(sum1,sum2);
int SECOND = ans % 60;
int MINUTE = (ans % 3600) / 60;
int HOUR = ans / 3600;
if(sum1 < sum2) HOUR *= -1;
Time NEW(HOUR, MINUTE, SECOND);
return NEW;
} //计算时间差,可正可负
friend ostream & operator << (ostream & os, const Time & tm ); //流输出运算符
};
ostream & operator << (ostream & os, const Time & tm ){
string t = to_string(tm.m_hour), m = to_string(tm.m_minute), s = to_string(tm.m_second);
if(t.size() == 1 )
t = "0" + t;
if(t[0] == '-' && t.size() == 2)
t = "-0" + to_string(t[1] - '0');
if(m.size() == 1)
m = "0" + m;
if(s.size() == 1)
s = "0" + s;
os << t << ":" << m << ":" << s;
return os;
}
class WorldTime:public Time{
private:
int m_timezone;
public:
WorldTime(int timezone, int hour, int minute, int second):Time(hour, minute, second){
if(timezone <= 12 && timezone >= -12)
m_timezone = timezone;
else
m_timezone = 0;
}
WorldTime(const WorldTime &wt){
this->m_timezone = wt.m_timezone;
this->m_hour = wt.m_hour;
this->m_minute = wt.m_minute;
this->m_second = 0;
}
Time operator - (const WorldTime & tm){
int sum1 = (m_hour - m_timezone) * 3600 + m_minute * 60 + m_second;
int sum2 = (tm.m_hour - tm.m_timezone) * 3600 + tm.m_minute * 60 + tm.m_second;
int ans = max(sum1,sum2) - min(sum1,sum2);
int SECOND = ans % 60;
int MINUTE = (ans % 3600) / 60;
int HOUR = ans / 3600;
if(sum1 < sum2) HOUR *= -1;
Time NEW(HOUR, MINUTE, SECOND);
return NEW;
}
WorldTime operator++(int){
WorldTime temp(*this);
this->m_timezone++;
if(m_timezone > 12)
m_timezone = -12;
return temp;
}
void convert(int timezone){
if(timezone > 12 || timezone < -12)
timezone = 0;
m_hour -= this->m_timezone - timezone;
if(m_hour < 0)
m_hour += 24;
if(m_hour > 24)
m_hour -= 24;
m_timezone = timezone;
}
friend ostream &operator <<(ostream &os, const WorldTime &tm);
};
ostream &operator <<(ostream &os, const WorldTime &tm){
string str;
if(tm.m_timezone >= 0)
if(to_string(tm.m_timezone).size() == 1)
str = "+0" + to_string(tm.m_timezone);
else
str = "+" + to_string(tm.m_timezone);
else{
if(to_string(tm.m_timezone).size() == 2)
str = "-0" + to_string(to_string(tm.m_timezone)[1] - '0');
else
str = to_string(tm.m_timezone);
}
os << "[" << str << "] " << static_cast<Time>(tm);
return os;
}
int main()
{
cout << "----------Section 1----------" << endl;
Time tm1(8,12,153), tm2;
cout << tm1 << endl;
cout << tm2 << endl;
cout << tm2 - tm1 << endl;
cout << "----------Section 2----------" << endl;
WorldTime wtm1(12, 7, 14, 29), wtm2(-10, 23, 10, 9), wtm3(wtm2);
cout << wtm1 << endl;
cout << wtm2 << endl;
cout << wtm3 << endl;
cout << wtm2 - wtm1 << endl;
cout << "----------Section 3----------" << endl;
wtm1++;
cout << wtm1 << endl;
wtm2.convert( 20 );
wtm3.convert( 8 );
cout << wtm2 << endl;
cout << wtm3 << endl;
cout << "----------Finish-------------" << endl;
return 0;
}