资源描述
“信息与计算科学”专业
《C++语言程序设计》课程设计
班级 计算科学
姓名
学号
指导教师
设计日期 2016·春·19周~20周
(一)、设计菜单选择程序。
菜单是应用程序的界面,通过控制语句改变程序执行的顺序,设计菜单是程序设计的基础。本设计分两步:
第一步:设计一个菜单程序。
1. 菜单内容:程序运行后,给出3个菜单项的内容和输入提示,如下:
1) 利用克莱姆法则求解线性方程组
2) 统计一篇英文文章的单词数
3) 退出程序
第二步:为上述菜单项配上相应的功能。
开始
选择运算
求
解
线
性
方
程
组
求
解
单
词
的
个
数
退
出
结束
1.流程图:
2.程序优缺点:
优点: 采用了 动态开辟二维数组,传递不知道大小的二维数组,程序规范,可读性强。
缺点:采用递归算法,增加了程序的时间复杂度。
3.代码段:
#include<iostream>
#include<string>
#include <stdlib.h>
#include<windows.h>
using namespace std;
double **open_up(int row,int line);
double Price(int row,int line,double *a);
void Head();
void Cramer();
void Statis_Words();
int main()
{
char ch; // 选择变量
while(1)
{
Head();
cout<<"\t\t选择要进行的程序:"<<endl;
ch = cin.get();
cout<<endl;
switch(ch)
{
case '1':system("cls");Cramer();break;
case '2':system("cls");Statis_Words();break;
case '3':system("cls"); cout << " 退出程序" << endl; exit(0);break;
default :system("cls");cout<<"\t\t 输入有误 "<<endl;
}
cin.get();
}
return 0;
}
void Head()
{
cout<<"\t\t 菜单选择程序 "<<endl;
cout<<"\t\t "<<endl;
cout<<"\t\t "<<endl;
cout<<"\t\t 1.克莱姆法则解线性方程组 "<<endl;
cout<<"\t\t 2.统计英语文章单词数 "<<endl;
cout<<"\t\t 3. 结 束 "<<endl;
cout<<"\t\t "<<endl;
cout<<"\t\t "<<endl;
}
void Cramer()
{
int m = 0,n = 0,i = 0,k = 0,j = 0,h = 0;
double Quit = 0.0,l = 0.0;
double **a = open_up(15,15); //动态开辟二维数组
double **e = open_up(15,15); //动态开辟二维数组
double **T = open_up(15,15); //动态开辟二维数组
double **W = open_up(15,15); //动态开辟二维数组
double P[15] = {0.0},d[15] = {0.0};
cout << "\t\t克莱姆法则计算矩阵的值" << endl;
cout << "输入所求线性方程组的系数矩阵";
cout << "输入行数m和列数n" << endl;
cin >> m >> n;
cout<<"输入矩阵"<<endl;
for(i = 0;i < m;i++)
{
for(j = 0;j < n;j++)
{
cin >> a[i][j];
}
}
cout<<endl;
Quit = Price(n,n,(double *)a);
cout << "系数矩阵的值为:"<<Quit<<endl;
cout<<"输入方程组的解矩阵"<<endl;
for(i = 0;i < n;i++)
{
cin >> d[i];
}
for(i = 0;i < m;i++)
{
for(j = 0;j < n;j++)
{
e[i][j] = a[i][j];
}
}
for(j = 0;j < n;j++)
{
for(i = 0;i < m;i++)
{
a[i][j] = d[i];
}
for(i = 0;i < m;i++)
{
P[j] = Price(n,n,(double*)a)/Quit; //强制类型转换
}
cout << "x[" << j << "]=" << P[j] <<endl;
for(h = 0;h < m;h++) //重置矩阵
{
a[h][j] = e[h][j];
}
}
}
void Statis_Words()
{
char ch = '\0';
int count = 0,word = 0;
cout<<"输入一片英语文章 以零结尾\n "<<endl;
while ( (ch = cin.get()) != '0' )
{
if((ch >= 0 && ch <= 64) || (ch >= 91 && ch <= 96) || (ch > 122 && ch < 127)) //判断是否为
{
word = 0;
}
else
{
if(0 == word)
{
word = 1;
count++;
}
}
}
cout<<"文章一共有"<<count<<"个单词"<<endl;
}
double Price(int row,int line,double *a)//求矩阵行列式的递归函数
{
int i = 0,j = 0,c = 0,p = 0,q = 0;
double sum = 0;
double **ele = open_up(row,line);
//动态开辟二维数组
if(row == 1)
{
return *a;
}
for(i = 0;i < row;i++) //递归法求解行列式的值
{
for(c = 0;c < row;c++)
{
if(c < i)
{
p=0;
}
else
{
p=1;
}
for(j = 0;j < row - 1;j++)
{
ele[c][j] = *( a+row*(c+p) + (j+1) );
}
}
if(i % 2 == 0)
{
q = 1;
}
else
{
q = -1;
}
sum += *(a+i*row+0) * q * Price(row-1,row-1,(double *)ele);
}
return sum;
}
double **open_up(int row,int line) // 动态开辟二维数组
{
double **ele = new double *[row];
for (int i = 0; i < row; i++)
{
ele[i] = new double[line];
}
return ele;
}
4.程序运行截图:
(二)、有理数的四则运算。
有理数就是两个整数的比率,通常表示为,分母不能为0。
本设计要求设计一个Rational(有理数)类,实现有理数的四则运算,该类型的对象使用起来要像使用基本类型的对象一样自然。具体要求如下:
1. 抽象Ration类,包含两个数据成员(分子、分母),比如有理数可以用对象表示为。
2. 如果分子分母有公约数,应该约分,例如应表示为。根据需要,有时要将表示为,或者将表示为
重载相应的运算符(输入、输出、加、减、乘、除)。比如,要计算,希望像普通加法一样操作,和相加得,算数表达式为。又如,想使用如下形式直接输入分子分母
cin << r ;
//输入
cout >> r;
//输出
则需要重载这两个流运算符。
1.流程图:
小数转换
转换
结束
执行减法
执行加法
执行乘法
开始
创建分数对象
执行除法
开始
开始
开始
创建分数对象
创建分数对象
创建分数对象
执行除法
执行除法
执行除法
执行乘法
执行乘法
执行加法
执行加法
执行减法
2.程序优缺点:
优点: 采用了友元函数实现运算符重载,使用windows命名规则程序规范,可读性强,使用外部接口让程序更安全。
缺点: 部分函数为类的友元函数,破坏了类的完整性。
3.代码段:
#include<iostream>
#include<stdlib.h>
using namespace std;
int gcd(int a, int b) ;
class Ration
{
public:
Ration(int a = 0,int b = 0):numer(a),denom(b)
{
}
void decide ();
void trans ();
void input ();
friend Ration operator -(Ration c1,Ration c2);
friend Ration operator +(Ration c1,Ration c2);
friend Ration operator *(Ration c1,Ration c2);
friend Ration operator /(Ration c1,Ration c2);
friend int gcd(int a, int b);
friend istream & operator >> (istream &in,Ration &c );
friend ostream & operator << (ostream &out,Ration &c );
private:
int numer;
int denom;
};
void Ration :: trans () //转变为小数
{
decide();
double c = (double)numer/(double)denom;
cout << "小数形式为 "<< c <<endl;
}
void Ration :: decide() // 判别是否可以写成分数
{
if(0 == denom)
{
cout << "分母不能为零";
exit(0);
}
}
Ration operator +(Ration c1,Ration c2)
{
c1.decide();
c2.decide();
Ration c3;
if(c1.denom == c2.denom)
{
c3.denom = c2.denom;
c3.numer = c1.numer + c2.numer;
}
else
{
c3.denom = c1.denom * c2.denom/gcd(c1.denom,c2.denom);
c3.numer = c1.numer* c3.denom / c1.denom + c2.numer*c3.denom /c2.denom ;
}
return c3;
}
Ration operator -(Ration c1,Ration c2)
{
c1.decide();
c2.decide();
Ration c3;
if(c1.denom == c2.denom)
{
c3.denom = c2.denom;
c3.numer = c1.numer - c2.numer;
}
else
{
c3.denom = c1.denom * c2.denom/gcd(c1.denom,c2.denom);
c3.numer = c1.numer* c3.denom / c1.denom - c2.numer*c3.denom /c2.denom ;
}
return c3;
}
Ration operator *(Ration c1,Ration c2)
{
c1.decide();
c2.decide();
Ration c3;
c3.denom = c1.denom * c2.denom;
c3.numer = c1.numer * c2.numer;
return c3;
}
Ration operator /(Ration c1,Ration c2)
{
c1.decide();
c2.decide();
Ration c3;
c3.numer = c1.numer * c2.denom;
c3.denom = c1.denom * c2.numer;
return c3;
}
istream & operator >> (istream &in,Ration &c )
{
//c.decide();
cout<<"输入分子分母\n";
in >>c.numer;
cin.get();
in >> c.denom;
return in;
}
ostream & operator << (ostream &out,Ration &c )
{
//c.decide();
if(c.numer != 0)
{
int GCD = gcd(c.numer,c.denom) ;
if(GCD <= 1)
{
out<<c.numer<<"/"<<c.denom <<endl;
}
else
{
out<<c.numer/GCD<<'/'<<c.denom/GCD<<endl;
}
}
else
{
out<<'0'<<'\n';
}
return out;
}
int gcd(int a, int b) // 求最小公倍数
{
int n = b;
int c = a % b;
while(c!=0)
{
a = b;
b = c;
c = a % b;
}
return b;
}
int main()
{
Ration A;
Ration B;
Ration c;
cout << "请输入分数A"<<endl;
cin >> A;
cout << "请输入分数B"<<endl;
cin >> B;
cout <<" B = " << B;
cout <<" A = " << A;
c = B / A;
cout <<"c = B / A = "<<c<<endl;
c = B * A;
cout <<"c = B * A = "<<c<<endl;
c = B + A;
cout <<"c = B + A = "<<c<<endl;
c = B - A;
cout <<"c = B - A = "<<c<<endl;
c.trans();
return 0;
}
4.程序截图:
(三)、职工信息表设计。
使用继承的方法,编写最多能输入10个职工的信息表,再根据这个表产生一个职工信息简表,并利用多态性实现信息的输出。设计要求实现如下功能:
1. 建立职工信息数据,包括职工编号、姓名,性别和年龄。
2. 根据职工信息表,建立只含姓名和年龄的职工信息简表。
3. 使用继承的方法构造2个类,使用相应的对象数组放置10个职工信息。
4. 编写同名display( )成员函数,用来输出数组的内容。
5. 编写函数printer( ),用来根据实际对象输出它们的内容。
1.流程图
: 开始
开始
类对象初始化
打印类对象数组1
打印类对象数组2
调用printer函数
选择查询职员
结束
2.程序优缺点:
优点:使用windows命名规则程序规范,可读性强,代码精炼,时间复杂度低,空间复杂度低
缺点: 功能较弱,操作性低。
3.代码段:
#include<iostream>
#include<iomanip>
#include<string>
using namespace std;
class Employee_one
{
public:
Employee_one(int n,char *nam,char s,int a):num(n),name(nam),sex(s),age(a){}
virtual void display();
int getnum()
{
return num;
}
char* getname()
{
return name;
}
char getsex()
{
return sex;
}
int getage()
{
return age;
}
private:
int num;
char *name;
char sex;
int age;
};
class Employee_two:public Employee_one
{
public:
Employee_two(int n,char* nam,char s,int a,int w):Employee_one(n,nam,s,a),wages(w){}
void display();
int getwages()
{
return wages;
}
private:
int wages;
};
void Employee_one::display()
{
cout<<setw(15)<<"\nname:"<<name
<<setw(15)<<setiosflags(ios::right)
<<"age:"<<age
<<setw(15)<<setiosflags(ios::left)<<"sex:"<<sex<<setw(15)
<<setiosflags(ios::left)<<"num:"<<num;
}
void Employee_two :: display()
{
cout<<"name:"<<getname()<<setw(15)<<"age:"<<getage()<<endl; /*<<"\nwages:"<<wages*/;
}
void printer(Employee_two w2[])
{
int a = 0,i = 0;
cout<<"请输入编号:";
cin>>a;
if(a <= 10)
{ for (i = 0;i < 10;i++)
{
if (w2[i].getnum()==a)
{
cout<<"name:"<<w2[i].getname()<<"\nage:"<<w2[i].getage()<<"\nwages:"
<<w2[i].getwages()<<"\nsex:"<<w2[i].getsex()<<"\nnum:"<<w2[i].getnum();
}
}
}
else
{
cout<<"编号错误差无此人";
}
}
int main()
{
Employee_one w1[10] =
{
Employee_one(1,"ci",'m',18),Employee_one(2,"cai",'m',19),
Employee_one(3,"xi",'f',18),Employee_one(4,"su",'m',20),
Employee_one(5,"li",'m',20),Employee_one(6,"yan",'m',19),
Employee_one(7,"yi",'m',18),Employee_one(8,"xiu",'m',21),
Employee_one(9,"su",'m',17), Employee_one(10,"men",'m',22)
};
Employee_two w2[10]=
{
Employee_two(1,"ci",'m',18,800),Employee_two(2,"cai",'m',19,700),
Employee_two(3,"xi",'f',18,900),Employee_two(4,"su",'m',20,750),
Employee_two(5,"li",'m',20,860),Employee_two(6,"yan",'m',19,900),
Employee_two(7,"yi",'m',18,1000),Employee_two(8,"xiu",'m',21,680),
Employee_two(9,"su",'m',17,1500),Employee_two(10,"men",'m',22,700)
};
cout<<"职工信息数据显示如下:";
for(int i = 0;i < 10; i++)
{
Employee_one *p= w1+i;
p->display();
cout << '\n';
}
cout<<"\n";
cout<<"职工信息简表如下:\n";
for(int j = 0;j < 10;j++)
{
Employee_two *p = w2 + j;
p->display();
cout<<"\n";
}
cout<<"实际对象信息为:\n";
printer(w2);
cout<<"\n";
return 0;
}
4.程序截图:
(四).高校人事管理系统:
1、问题描述(功能要求):
某高校,主要人员有:在职人员(行政人员、教师、双肩挑人员(注:教师编制,担任领导职务))、退休人员、返聘人员和临时工。现在,需要存储这些人员的人事档案信息:编号、姓名、性别、年龄、职务、职称、政治面貌、最高学历、任职时间、来校时间。
要求:
1) 添加删除功能:能根据学校人事的变动情况,添加删除记录;
2) 查询功能:能根据编号和姓名进行查询;
3) 编辑功能(高级):根据查询对相应的记录进行修改,并存储;
4) 统计功能:能根据多种参数进行人员的统计(在职人数、党员人数、女工人数、高学历高职称人数);
5) 保存功能:能对输入的数据进行相应的存储,要求重载插入和提取符以完成数据的保存和打开。
6) 人员编号在生成人员信息时同时生成,每输入一个人员信息,编号顺序加1。
2、问题的解决方案:
根据系统功能要求,可以将问题解决分为以下步骤:
1) 应用系统分析,建立该系统的功能模块框图以及界面的组织和设计;
2) 分析系统中的各个实体及它们之间的关系包括属性和行为;
3) 根据问题描述,设计系统的类层次;
4) 完成类层次中各个类的描述(包括属性和方法);
5) 完成类中各个成员函数的定义;
6) 完成系统的应用模块;
7) 功能调试;
完成系统总结报告以及系统使用说明书。
高校人事管理系统包括的功能:
1.流程图
结束
动态增加容量
增加教职工
删除教职工
显示教职工
查找教职工
修改教职工
统计职务人数
执行销毁函数退出
开始
选择函数
开始
开始
开始
选择函数
选择函数
选择函数
v
统计职务人数
删除教职工
增加教职工
查找教职工
显示教职工
修改教职工
执行销毁函数退出
执行销毁函数退出
修改教职工
显示教职工
查找教职工
增加教职工
删除教职工
统计职务人数
v
动态增加容量
结束
2程序优缺点:
优点:采用动态类数组建立,并设立了数组的有效长度,并且自动增加数组长度,不必使用文件结构,降低了空间复杂度,代码规范可读性性强,封装紧密,安全。采用了《数据结构》链表的思想
缺点:界面设计有所欠缺。部分函数算法还需加强
3程序代码:
#include <iostream>
#include <string>
#include <stdlib.h>
#include<windows.h>
using namespace std;
#define SIZE_INTE 10 // 初始类数组的长度
int usedsize = 0; // 类数组的有效长度
class Personnel_Staff //人员类
{
public:
void Add(); //新增教职工信息
void Display(); //显示已有教职工信息
void Edit(); //修改教职工信息
bool Search(int Num ,char *Na); //查找教职工
void Delete(); //删除教职工信息
void State(); //统计信息
int GetSer_Number()
{
return Ser_Number;
}
int GetAge()
{
return Age;
}
int GetOff_Time()
{
return Off_Time;
}
int GetStart_Time()
{
return Start_Time;
}
char *GetName()
{
return Name;
}
char *GetSex()
{
return Sex;
}
char *GetJob()
{
return Job;
}
char *GetTitle_Po()
{
return Title_Po;
}
char *GetPol_Status()
{
return Pol_Status;
}
char *GetEdu_Certi()
{
return Edu_Certi;
}
private:
int Ser_Number; //编号
int Age; //年龄
int Off_Time; //任职时间
int Start_Time; //来校时间
char Name[20]; //姓名
char Sex[20]; //性别
char Job[20]; //职务
char Title_Po[20]; //职称
char Pol_Status[20]; //政治面貌
char Edu_Certi[20]; //学历
};
//######################################################*新增教职工信息
void Personnel_Staff::Add()
{
//Tusedsize = usedsize;
int f = 1;
cout << "##########新增职工档案#############" << endl;
cout << "输入教职工编号: ";
cin >> Ser_Number;
//ser_Number = usedsize;
cout << "输入教职工姓名: ";
cin >> Name;
cout << "输入教职工性别: ";
cin >> Sex;
cout << "输入教职工年龄: ";
cin >> Age;
while (1)
{
cout << "教职工分类(行政,教师,双肩挑,退休,返聘,临时工):";
cin >> Job;
if ( strcmp(Job,"行政") == 0
|| strcmp(Job,"教师") == 0
|| strcmp(Job,"双肩挑") == 0
|| strcmp(Job,"退休") == 0
|| strcmp(Job,"返聘") == 0
|| strcmp(Job,"临时工") ==0)
{
break;
}
else
cout << "错误!!! 请重新输入 ! " << endl;
}
while (1)
{
cout << "教职工职称(讲师,教授,副教授,无): ";
cin >> Title_Po;
if (strcmp(Title_Po,"无") == 0
|| strcmp(Title_Po,"讲师") == 0
|
展开阅读全文