软件课程设计l总结论文、、
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
编号:()字号
《软件课程设计》报告
班级:
姓名:
学号:
指导老师:张振环
中国矿业大学计算机科学与技术学院
2012年12月
软件课程设计任务书
专业年级:
学生姓名:
任务下达日期:2012 年10月20 日
课程设计日期:2012 年1月日至2013年 1 月10 日
课程设计题目:面向过程
类别题目序号成绩面向过程 5.判断日期与星期
7数制转化()
面向对象 5. 设计一个类CStudent 3.
利用虚函数手段,按照3种不
同的计算方法来求出
Fibonacci数列的第n项(的具
体项值)并输出。
图形界面 1.通过MFCAPPWIZARD
创建一个简单的可视化()
数据结构 2.假设有一个循环链表的
长度大于1,且表中既无头
结点也无头指针。
已知p
为指向链表中某结点的指
针,试编写算法在链表中
删除结点p 的前趋结点。
4 .设计一个统计选票的算
法,输出每个候选的得票
结果(假设采用单链表存
放选票,候选人编号依次
为1,2,3,……,N,且
每张选票选且只选一人)
(1、3。
).
软件课程设计指导教师评阅书
指导教师评语(①基础理论及基本技能的掌握;②独立解决实际问题的能力;
③研究内容的理论依据和技术方法;④取得的主要成果及创新点;⑤工作态度及工作量;⑥总体评价及建议成绩;⑦存在问题等):
成绩:指导教师签字:
年月日
目录
1.1过程设计题5-------判断日期与星期(第一阶段.5)
1.1 需求分析 (6)
1.2 概要设计 (6)
1.3 详细设计与编码 (7)
1.4 调试分析 (8)
1.5 用户使用说明 (9)
1.6 设计心得 (9)
1.2面向过程设计题7-----数制转化(sy7.cpp)
2.1 需求分析 (9)
2.2 概要设计 (10)
2.3 详细设计与编码 (11)
2.4 调试分析 (11)
2.5 用户使用说明 (12)
2.6 设计心得 (12)
2.1面向对象设计题5------设计一个类CStudent(第二阶段5.cpp)
3.1 需求分析 (12)
3.2 概要设计 (13)
3.3 详细设计与编码 (14)
3.4 调试分析 (16)
3.5 用户使用说明 (19)
3.6 设计心得 (20)
2.2面向对象设计题7---------关于磁盘文档的输入输出(7.cpp)
4.1 需求分析 (21)
4.2 概要设计 (21)
4.3 详细设计与编码 (22)
4.4 调试分析 (22)
4.5 用户使用说明 (23)
4.6 设计心得 (24)
3.1图形界面1---------简单可视化()
5.1 需求分析................................................................................. .24 5.2 概要设计.. (24)
5.3 详细设计与编码 (25)
5.4调试分析 (25)
5.5 用户使用说明 (26)
5.6 设计心得 (26)
4.1数据结构2------删除结点p 的前趋结点(数据结构2.cpp)
6.1 需求分析 (27)
6.2 概要设计 (27)
6.3 详细设计与编码 (28)
6.4 调试分析 (28)
6.5 用户使用说明 (29)
6.6 设计心得 (29)
4.2数据结构4--------统计选票(数据结构3.cpp)
7.需求分析 (29)
7.概要设计 (30)
7.详细设计与编码 (31)
7.调试分析 (32)
7.用户使用说明 (43)
7.设计心得 (34)
五.课程设计总结 (34)
1.1面向过程第五题让用户仅输入一个表示日期的年月日,则程序就应计算出那一天是星期几。
(1)需求分析:
当我们处理查找具体年份月日是周几的问题,往往会遇到闰年平年的问题,还有七天一循环的问题。
因此实现此类算法是很有必要的。
(2)概要设计:
1.对于指定具体年月日所在本年的第多少天,有如下算法。
switch(m) //判断该日期是该年的第几天
{
case 1:j=d; break;
case 2:j=31+d; break;
case 3:j=59+d; break;
case 4:j=90+d; break;
case 5:j=120+d; break;
case 6:j=151+d; break;
case 7:j=181+d; break;
case 8:j=212+d; break;
case 9:j=243+d; break;
case 10:j=273+d; break;
case 11:j=304+d; break;
case 12:j=334+d; break;
} } 2.求解平年还是闰年的算法如下:
int leap(int year)
{
int leap;
leap=((year%4==0&&year%100!=0)||(year%400==0));
return (leap);
}
(3)详细设计与编码:
/*************************************************
Copyright (C), 2012- , mekinglong of cumtcs
File name:软件设计普通题5(软设普5.cpp)
Author: 计科11-2 刘凯宁
Version: 1.00 Date: 12.10.16
Description: 该程序让用户仅输入一个表示日期的年月日,则程序就应计算出那一天是星期几:
采用函数方法,先判断y 年的第一天是星期几,再求具体日期是星期几 Others: ....
Function List: // 主要函数列表,每条记录应包括函数名及功能简要说明 1.main() 完成各种提示与主操作输入输出
History:
<author> <time> <version > <desc>
*****************************************************/
#include<iostream>
using namespace std;
int main()
{
int a=1; while(a==1) { int y1,m,d,y,e,f,g,h,i,j,k; bool leap;
cout<<"该程序可以判断你输入的日期是星期几。
"<<endl; cout<<"也可以判断该年的1月1日是星期几。
"<<endl; cout<<"***************************"<<endl; cout<<"***************************"<<endl; cout<<"请输入year :"<<endl;
cin>>y;
if((y%4==0&&y%100!=0)||(y%400==0)) leap=true; //判断y 是不是闰年
else leap=false;
cout<<"请输入month :"<<endl; cin>>m;
if(m>12||m<1) { cout<<"输入错误,请重新输入:"<<endl; cin>>m; }
cout<<"请输入day :"<<endl; cin>>d;
if(!leap&&m==2&&d==29)
{
cout<<y<<"是平年,二月份只有28天,请重新输入day:"<<endl; cin>>d; }
y1=y-1;
e=(y1/400)*3+y1%400/100; //e 为百年不闰的年数
计算出该月日是第多少天 g=f*366+(y1-f)*365+1; Cin>>year>>s; Cin>>month>>day ; 开始 先判断y 年的
第一天是星期
几
先判断y 年的该天是星期几 结束
f=y1/4-e; //f为第1年到第y年的闰年数
g=f*366+(y1-f)*365+1; //g为第1年到第y年的天数
h=g%7;
switch(h) //先判断y年的第一天是星期几
{
case 0:i=7;cout<<y<<"年的1月1日是星期天。
"<<endl; break;
case 1:i=1;cout<<y<<"年的1月1日是星期一。
"<<endl; break;
case 2:i=2;cout<<y<<"年的1月1日是星期二。
"<<endl; break;
case 3:i=3;cout<<y<<"年的1月1日是星期三。
"<<endl; break;
case 4:i=4;cout<<y<<"年的1月1日是星期四。
"<<endl; break;
case 5:i=5;cout<<y<<"年的1月1日是星期五。
"<<endl; break;
case 6:i=6;cout<<y<<"年的1月1日是星期六。
"<<endl; break;
}
cout<<endl;
switch(m) //判断该日期是该年的第几天
{
case 1:j=d; break;
case 2:j=31+d; break;
case 3:j=59+d; break;
case 4:j=90+d; break;
case 5:j=120+d; break;
case 6:j=151+d; break;
case 7:j=181+d; break;
case 8:j=212+d; break;
case 9:j=243+d; break;
case 10:j=273+d; break;
case 11:j=304+d; break;
case 12:j=334+d; break;
}
if(leap&&m>2)j=j+1;
k=(j%7+i-1)%7;
switch(k) //判断具体日期是星期几
{
case 0:cout<<y<<"年"<<m<<"月"<<d<<"日"<<"是星期日"<<endl; break;
case 1:cout<<y<<"年"<<m<<"月"<<d<<"日"<<"是星期一"<<endl; break;
case 2:cout<<y<<"年"<<m<<"月"<<d<<"日"<<"是星期二"<<endl; break;
case 3:cout<<y<<"年"<<m<<"月"<<d<<"日"<<"是星期三"<<endl; break;
case 4:cout<<y<<"年"<<m<<"月"<<d<<"日"<<"是星期四"<<endl; break;
case 5:cout<<y<<"年"<<m<<"月"<<d<<"日"<<"是星期五"<<endl; break;
case 6:cout<<y<<"年"<<m<<"月"<<d<<"日"<<"是星期六"<<endl; break; }
cout<<"------------------------------"<<endl;
cout<<"------------------------------"<<endl;
cout<<"选择是否继续运行程序:1(继续运行)/0(跳出程序)"<<endl;
cin>>a;
}
return 0;
}
if(leap(year)&&month>=3) days=days+1;
s=s+(days-1)%7;
if(s>7)
s=s%7;
cout<<s<<endl;
return 0;
}
(4)运行结果
(5)试调分析
1. year,month,day,days,s的类型是int型的。
2.对于平年闰年的分析,要分别对待,加以区分。
3. 注意体会尝试程序的健壮性。
4.尝试用其他方法完成该程序。
(6)用户说明
该程序可以判断你输入的日期是星期几;
也可以判断该年的1月1日是星期几。
(7)设计心得
本程序主要是求出n的反序数,利用do-while循环语句可容易求出n的反序数。
程序设计中要联系所学知识,本题较简单,因此可以用简单的语句求出结果。
1.2面向过程第七题将输入的罗马数据化为10进制数。
假设罗马数据中只使
用如下7个“基值”字母:M、D、C、L、X、V、I,分别用来表示1000、500、100、50、10、5、1。
(1)需求分析:我们经常会遇到一些数制间的转化,这些繁杂但有规律可循的计算,可以编写程序让计算机来完成。
(2)设计概要
1.罗马型转成十进制
for(a=0,i=0;str[i]!=0;i++) //对输入的罗马数据即字母逐个判断,再用for循环求值
{ switch (str[i])
{
case 'M':a=a+1000;break;
case 'D':a=a+500;break;
case 'C':a=a+100;break;
case 'L':a=a+50;break;
case 'X':a=a+10;break;
case 'V':a=a+5;break;
case 'I':a=a+1;break;
default :break;
}
2.十进制转化成罗马型
for(i=0;i<7;i++)
{ num[i]=n/date1[i]; //用数组记录每个基值的个数 n=n%date1[i]; //求每除一次基值后的余数 for(j=0;j<num[i];j++) //输出每个基值总数
cout<<date[i]; }
(3)详细设计与编码:
/************************************************* File name:软件设计普通题 7(软设普7.cpp )
Author: 计科11-2 刘凯宁
Description: 该程序罗马数据化为10进制数,0进制正整数转换为罗马数据: 采用函数,数组,循环,选择等方法 Function List: 1.main() // 主要函数列表,每条记录应包括函数名及功能简要说明 完成各种提示与主操作输入输出 2.void rome() // 将罗马数据转换成十进制 3.void number() //将十进制转换成罗马数据 *****************************************************/ #include<iostream> #include<string> using namespace std;
string date="MDCLXVI";
int date1[7]={1000,500,100,50,10,5,1}; int i,a,j,n,m; string str; int num[10]; void rome(); void number();
int main() //主函数 {
int a=1; 1 2 while(a) {
cout<<"选择转化类型(1为转成十进制/2为转成罗马型):"<<endl; cin>>m;
if(m==1) rome(); //判断是哪种数据的转换 else number(); cout<<"选择是否继续运行程序:1(继续运行)/0(跳出程序"<<endl; cin>>a;
}
输入1/2 判断输入的值 开始
十进制 罗马数
制 结束
return 0;
}
void rome() //将罗马数据转换成十进制
{
cout<<"输入罗马数据(M D C L X V I):"<<endl;
cin>>str;
for(a=0,i=0;str[i]!=0;i++) //对输入的罗马数据即字母逐个判断,再用for循环求值
{ switch (str[i])
{
case 'M':a=a+1000;break;
case 'D':a=a+500;break;
case 'C':a=a+100;break;
case 'L':a=a+50;break;
case 'X':a=a+10;break;
case 'V':a=a+5;break;
case 'I':a=a+1;break;
default :break;
}
}
cout<<"转化成十进制:"<<a<<endl;
}
void number() //将十进制转换成罗马数据
{
cout<<"输入十进制数据:";
cin>>n;
for(i=0;i<7;i++)
{
num[i]=n/date1[i]; //用数组记录每个基值的个数
n=n%date1[i]; //求每除一次基值后的余数
for(j=0;j<num[i];j++) //输出每个基值总数
cout<<date[i];
}
cout<<endl;
}
(4)调试分析
1程序开始不可少语句 int f(char);
int m=0;
char x,y;//设“基值”并作零初始化,若不做初始化,字母输出任意值。
2.将对应的字母返回对应的值,然后把数值累加起来,除了对应之外没有其他难点
3.尝试着用其他方法编写
2.5用户使用说明:
用户直接从键盘输入罗马数字,按回车键可以方便得到输出的阿拉伯数字。
用户直接从键盘输入十进制数字,按回车键可以方便得到输出的罗马数字
2.6设计心得:
此程序在设计之前,一定要分析好设计思路,分析每个罗马字母中返回的数值,做好相应的处理。
2.1面向对象第五题设计一个类CStudent,类中包含一个学生的基本数据如下:
编号,姓名,性别,年龄,数学成绩,计算机成绩,外语成绩。
并假设编号为整数,且从1号往后连续编码;姓名为字符串,性别为字符。
(1)需求分析
在信息化的时代,电脑越来越成为了人们的帮手。
面对大量的数据管理,计算机能帮我们很大的忙。
(2)设计概要
1.类CStudent,类中包含一个学生的基本数据如下:
编号,姓名,性别,年龄,数学成绩,计算机成绩,外语成绩
protected:
int num;
char name[30];
char sex;
int age;
double math;
double computer;
double english;
2.处理函数
void addstudent();
void findname(char[]);
void findnum(int);
void grade(int);
void display(int , char);
3.存盘
ofstream ofile("student1.txt",ios::app|ios::binary);
//以输出的方式打开一个二进制文件,若文件不存在建立一个新文件
if(!ofile)
{
cerr<<endl<<"学生信息文件打开错误!"<<endl;
abort(); //异常终止一个进程
}
ofile.write((char*)&sstruct,sizeof(sstruct));
//把sstruct的数据写入文件,(char*)&sstruct取出sstruct中的地址并转换为char指针,sizeof(sstruct)获取sstruct中数据
ofile.close(); //关闭文件
(3)详细程序
//在修改了源程序时出现cannot open file "Debug/第二阶段5.exe错误,只需从组建->全部重建
#include<iostream>
#include<fstream>
using namespace std;
class cstudent //声明一个类cstudent
{
protected:
int num;
char name[30];
char sex;
int age;
double math;
double computer;
double english;
public:
void addstudent();
void findname(char[]);
void findnum(int);
void grade(int);
void display(int , char);
};
struct stu_struct //声明一个结构体类型stu_struct
{
int num;
char name[30];
char sex;
int age;
double math;
double computer;
double english;
}sstruct; //定义一个结构体类对象
void cstudent::addstudent() //cstudent成员函数,对cstudent数据成员赋值
{
cout<<endl<<"请输入学生编号:";
cin>>num;
cout<<endl<<"请输入学生姓名:";
cin>>name;
cout<<endl<<"请输入学生性别(m/f):";
cin>>sex;
if(sex=='m'||sex=='f')
{
cout<<"输入正确!"<<endl;
}
else
{
cout<<"性别输入错误,请重新输入:";
cin>>sex;
}
cout<<endl<<"请依次输入学生数学、计算机、英语成绩:";
cin>>math>>computer>>english;
sstruct.num=num; //将类cstudent数据成员的值赋给stu_struct 的值赋给sstruct的数据成员
strcpy(,name);
sstruct.sex=sex;
sstruct.age=age;
sstruct.math=math;
puter=computer;
sstruct.english=english;
ofstream ofile("student1.txt",ios::app|ios::binary);
//以输出的方式打开一个二进制文件,若文件不存在建立一个新文件
if(!ofile)
{
cerr<<endl<<"学生信息文件打开错误!"<<endl;
abort(); //异常终止一个进程
}
ofile.write((char*)&sstruct,sizeof(sstruct));
//把sstruct的数据写入文件,(char*)&sstruct取出sstruct中的地址并转换为char 指针,sizeof(sstruct)获取sstruct中数据
ofile.close(); //关闭文件
}
//======根据编号查找学生信息====//
void cstudent::findnum(int number1)
{
ifstream ifile("student1.txt",ios::in|ios::binary);
//ifstream用来支持从磁盘文件的输入,ios::in|ios::binary:以输入的方式打开二进制文件
if(!ifile)
{
cerr<<endl<<"学生信息文件打开错误!"<<endl;
abort();
}
int i;
while(!ifile.eof()) //判断是不是文件结尾
{
ifile.read((char*)&sstruct,sizeof(sstruct)); ///读入文件中的数据
if(!ifile.eof())
if(sstruct.num==number1) //判断编号是否相等
{
i=0;
cout<<"编号:"<<sstruct.num<<endl;
cout<<"姓名:"<<<<endl;
cout<<"性别:"<<sstruct.sex<<endl;
cout<<"数学:"<<sstruct.math<<endl;
cout<<"计算机:"<<puter<<endl;
cout<<"英语:"<<sstruct.english<<endl;
}
}
if(i!=0)
cout<<"无此学生信息!"<<endl;
//=======根据学生名字查找学生信息========//
void cstudent::findname(char nam[30])
{
int i;
ifstream ifile("student1.txt",ios::in|ios::binary);
if(!ifile)
{
cerr<<endl<<"学生信息文件打开错误!"<<endl;
abort();
}
while(!ifile.eof())
{
ifile.read((char*)&sstruct,sizeof(sstruct));
i=strcmp(,nam);//字符串比较函数
if(!ifile.eof()) //加入此语句可以使最后一个学生信息不会输出两遍
if(i==0)
{
cout<<"编号:"<<sstruct.num<<endl;
cout<<"姓名:"<<<<endl;
cout<<"性别:"<<sstruct.sex<<endl;
cout<<"数学:"<<sstruct.math<<endl;
cout<<"计算机:"<<puter<<endl;
cout<<"英语:"<<sstruct.english<<endl;
}
}
ifile.close();
if(i!=0)
cout<<"未发现该学生信息!"<<endl;
}
//=====计算某编号的学生的总成绩和平均成绩======//
void cstudent::grade(int number)
{
double i;
//long inpos;
ifstream iofile("student1.txt",ios::in|ios::binary|ios::out); //打开二进制文件student.txt,可读可写
if(!iofile)
{
cerr<<endl<<"学生信息文件打开错误!"<<endl;
abort();
}
while(!iofile.eof())
{
iofile.read((char*)&sstruct,sizeof(sstruct));
if(!iofile.eof())
if(sstruct.num==number)
{
cout<<"姓名:"<<<<endl;
i=sstruct.math+puter+sstruct.english;
cout<<"总成绩:"<<i<<endl;
cout<<"平均成绩:"<<i/3<<endl;
}
}
iofile.close();
cerr<<"无此学生信息!";
}
//====列出总成绩超出n分的性别为s的同学的信息====//
void cstudent::display(int n,char s)
{
double i;
ifstream ifile("student1.txt",ios::in|ios::binary);//打开文件if(!ifile)
{
cerr<<endl<<"学生信息文件打开错误!"<<endl;
abort();
}
while(!ifile.eof())
{
ifile.read((char*)&sstruct,sizeof(sstruct));//读取数据
if(!ifile.eof())
if(sstruct.sex==s)
{
i=sstruct.math+puter+sstruct.english;
if(i>n)
{
cout<<"编号:"<<sstruct.num<<endl;
cout<<"姓名:"<<<<endl;
cout<<"性别:"<<sstruct.sex<<endl;
cout<<"数学:"<<sstruct.math<<endl;
cout<<"计算机:"<<puter<<endl;
cout<<"英语:"<<sstruct.english<<endl;
}
}
}
ifile.close();
cerr<<"无其它学生信息!";
}
int main()
{
cstudent cs1;
char ch1,ch2,nam[30];
int numb,fen,numbe;
cout<<endl;
cout<<"==========================学生信息管理系统==========================="<<endl;
while(true)
{
cout<<"请选择操作:1.输入学生信息;2.按编号查找;3.按姓名查找;"<<endl;cout<<"4.按编号查找总成绩和平均成绩;5.列出总成绩超出n分的性别为s的同学的信息;6.退出。
"<<endl;
cin>>ch1;
while(ch1!='1'&&ch1!='2'&&ch1!='3'&&ch1!='4'&&ch1!='5'&&ch1!='6'){cout<<"选择错误,请重新选择:";cin>>ch1;}
if(ch1=='1')
cs1.addstudent();
else if(ch1=='2')
{
cout<<"请输入要查找的学生编号:";
cin>>numb;
cs1.findnum(numb);
}
else if(ch1=='3')
{
cout<<"请输入要查找的学生姓名:";
cin>>nam;
cs1.findname(nam);
}
else if(ch1=='4')
{
cout<<"请输入学生编号:";
cin>>numbe;
cs1.grade(numbe);
}
else if(ch1=='5')
{
cout<<"请输入分数线和性别:";
cin>>fen>>ch2;
cs1.display(fen,ch2);
}
else break;
}
return 0;
}
(4)运行结果
1.输
入信
息
2.按
编号
查找
(5)使用说明
运行程序,根据提示完成操作。
(6)设计心得
用结构体来记录学生信息,并存入磁盘文件中。
需要注意的是读取磁盘文件时,文件的结束信息,以防止最后一个信息连续输出两遍。
2.2面向对象第三题利用虚函数手段,按照3种不同的计算方法来求出Fibonacci 数列的第n项(的具体项值)并输出。
具体地说,可通过在基类baseCla及其派生类fib1Cla、fib2Cla和fib3Cla中说明如下的同一个虚函数“virtual double fib(int n);”,来实现求Fibonacci 数列第n项值并返回的3种不同求解方法。
例如,可设计并使用已经在第4和第5章的练习中所实现的求解方法:简单变量“数据平移”法、使用数组的实现法以及使用递归函数的实现法。
(1)需求分析
Fibonacci数列第n项是经典的数学问题,因此有必要设计此类程序。
(2)设计概要
1.三种方法
fib(int n)
2.利用虚函数
virtual double fib(int n)
(3)详细设计
/*************************************************
Copyright (C), 2012-10- , mekinglong of cumtcs
File name: 软件设计普通题3(软设普3.cpp)
Author: 计科11-2 刘凯宁
Version: 1.00 Date: 12.10.22
Description: 该程序利用虚函数手段,按照3种不同的计算方法来求出Fibonacci数列的第n项(的具体项值)并输出。
采用面向对象的方法
Others: ....
Function List: //
History:
<author> <time> <version > <desc>
*****************************************************/
#include<iostream>
#include<iomanip>
using namespace std;
class baseCal
{public:
virtual double fib(int n)=0;
};
//数据平移法
class fib1cal:public baseCal
{public:
virtual double fib(int n);
};
double fib1cal::fib(int n)
{double newitem=1,f1=1,f2=1;
int i;
for(i=3;i<=n;i++) //循环语句
{
newitem=f1+f2; //距它最近"的前两项
f1=f2; //把后一项赋值给前一项
f2=newitem; //把距它最近"的前两项和"赋值给后一项}
return newitem;
}
//数组法
class fib2cal:public baseCal
{public:
virtual double fib(int n);
};
double fib2cal::fib(int n)
{
int i ;
double f[1000]={1,1};
for(i=2;i<n;i++)
{f[i]=f[i-2]+f[i-1];}
return f[n-1];
}
//递归法
class fib3cal:public baseCal
{public:
virtual double fib(int n);
};
double fib3cal::fib(int n)
{
double c;
if(n==1||n==2)c=1;
else c=fib(n-2)+fib(n-1);
return c;
}
//===//
void fun(baseCal *p,int n)
{
double d=p->fib(n);
cout.flags(ios::scientific);
cout.precision(15);
cout<<"fib("<<n<<")="<<d<<endl;
}
int main()
{
fib1cal obj1;
fib2cal obj2;
fib3cal obj3;
double n;
char ch1;
while(true)
{
cout<<"请选择操作:1数据平移法,2数组法,3递归法,4退出"<<endl;
cin>>ch1;
while(ch1!='1'&&ch1!='2'&&ch1!='3'&&ch1!='4')
{
cout<<"选择错误,请重新选择:";cin>>ch1;
}
if(ch1=='1')
{cout<<"请输入n值"<<endl;
cin>>n;
fun(&obj1 ,n);
}
else if(ch1=='2')
{cout<<"请输入n值"<<endl;
cin>>n;
fun(&obj2 ,n);
}
else if(ch1=='3')
{cout<<"请输入n值"<<endl;
cin>>n;
fun(&obj3 ,n);
}
else break;
}
return 0;
}
(4)运行结果
(5)设计心得
通过编写这个程序让我学会了如何用多种方法去解决一个问题。
3.1可视化
1.需求分析可视化能够更直观地反映问题。
2.设计概要
1.从Appwizard开始-----“HELLO”;
2.菜单和加速键;
3.对话框;
4.windows消息;
添加菜单,加速器
1.添加菜单资源,设置菜单属性(包括菜单名和它的ID标识)这要在菜单编辑器中进行过。
2.类向导,ClassWizard建立消息和成员函数的映射。
3.手工编辑成员函数。
对话框的设计
在MFC中对话框的功能被封装在CDialog类中,对话框分为模态对话框和非模态对话框。
控件作为对话框独立的小部件在对话框与用户进行交互起着重要作用,控件也是小窗口。
对话框的设计包括三部分:
1.对对话框模板设定
2.对对话框类的设计。
对话框类用来实现对话框的功能,一般需要在ClassWizard中从CDialog类中派生一个新类,再定控件成员变量和成员函数。
3.关于对话框的消息以及成员函数的实现。
Windows消息的有关概念和使用
Windows消息类型:标准Windows消息、控件通知消息和命令消息
1.WM-为前缀的都是标准Windows消息,它由窗口和视频处理,通常含有如何对消息进行处理一些参数。
2.从控件和其它子窗口传给父窗口的消息,称之为控件通知消息。
3.命令消息是指来自用户界面的对象的WM_COMMAND消息。
3.运行结果
4.1数据结构假设有一个循环链表的长度大于1,且表中既无头结点也无
头指针。
已知p为指向链表中某结点的指针,试编写算法在链表中删除结点p 的前趋结点。
4.1需求分析
在数据结构的学习中,链表是最常见的存储方式,链表的插入,删除,改正也就是很常用的操作,对它的学习就显得很有必要而且很有意义。
4.2概要设计
1. 对节点的删除,无疑先要定义一个结构体和指针,运来存放和查找要删除的节点struct Node *next
2.设计一个类求前驱节点:node1* getPriorNode(node1 *node)
3. 删除指向结点的前驱结点:delPriorNode( node1*node)
4. 输出原始链表:printList( node1*node)
5.主函数将操作后的链表输出。
4.3详细设计与编码
//假设有一个循环链表的长度大于1,且表中既无头结点也无头指针。
//已知p为指向链表中某结点的指针,试编写算法在链表中删除结点p 的前趋结点
#include<iostream>
using namespace std;
template<class T>
struct Node
{
T data;
Node *next;
Node *prior; //建立双向链表
};
template<class T>
class CLinkList
{
private:
Node<T> *Head;
public:
CLinkList();
void CreatList(int n);
void Delete(int e);
void ShowList();
template <class T>
CLinkList<T>::CLinkList()
{
Head=new Node<T>;
Head->next=Head;
Head->prior=Head;
}
template <class T>
void CLinkList<T>::CreatList(int n)
{
Node<T> *p,*s;
p=Head;
cout<<"请依次输入"<<n<<"个元素值:"<<endl;
for(int i=1;i<=n;i++)
{
s=new Node<T>;
cin>>s->data;
s->next=p->next;
p->next=s;
s->prior=p;
Head->prior=s;
p=s;
}
}
template <class T>
void CLinkList<T>::Delete(int e)
{
Node<T> *p;
p=Head->next;
while(p!=Head)
{
if(p->data==e)
{
p->prior->prior->next=p;
p->prior=NULL;
break;
}
else
p=p->next;
}
template <class T>
void CLinkList<T>::ShowList() {
Node<T> *p;
p=Head->next;
while(p!=Head)
{
cout<<p->data<<"\t";
p=p->next;
}
cout<<endl;
}
int main()
{
int n,e;
CLinkList<int> L;
cout<<"请输入链表长度:";
cin>>n;
L.CreatList(n);
L.ShowList();
cout<<"请输入指定节点大小:";
cin>>e;
L.Delete(e);
L.ShowList();
return 0;
}运行结果:
4.4调试分析
编写过程要细心,缺分号,括号的现象也有时发生
4.5用户使用说明
程序中的数字是从编程时输入的,平心而论该程序还有很大的改编空间,是一个静态的检验程序
4.6设计心得
进一步掌握了链表的基本操作,前驱指针在查找节点时的作用,类的整体设计和个类之间的关系,弄懂这些编程的要点,无论是在今后的学习还是调试过程中都是很有意义的。
4.2数据结构第四题设计一个统计选票的算法,输出每个候选的得票结果(假设采用单链表存放选票,候选人编号依次为1,2,3,……,N,且每张选票选且只选一人)提示:以单链表存放选票,每个结点的data域存放该选票所选的候选人。
用一个数组a统计得票结果。
4.1需求分析
1、设计一个统计选票的算法,输出每个候选人的得票结果
2、假设采用单链表存放选票,候选人编号依次为1,2,3,……,N,且每张选票选且只选一人
3、以单链表存放选票,每个结点的data域存放该选票所选的候选人。
用一个数组a统计得票结果。
4.2概要设计
用函数CreateList ( )动态建立一个单链表,链表中每个节点的data域为空,返回头节点。
Statistics( )函数统计各个后选人所得票数。
在主函数中先输入候选人数n,然后动态建立一维数组a[n]来存放每个候选人所得票数(如a[i]表示第i+1号候选人所得票数),统计选票时调用Statistics( )函数,将整个单链表全部遍历一遍,将各个候选人的得票个数计入到数组a[n]中,最后输出各个候选人的得票情况。
4.3详细设计与编码
流程图
开始
输入候选人人数
动态建立一维数组a[n]来存放每
个候选人所得票数
输入选票张数
用CreateList()函数动态建立一个
单链表,并返回头节点
调用ResearchList()函数进行票数统
计
输出各个候选人的得票情
况
结束
程序代码
//设计一个统计选票的算法,输出每个候选的得票结果
//(假设采用单链表存放选票,候选人编号依次为1,2,3,……,N,且每张选票选且只选一人)
#include<iostream>
#include<string>
using namespace std;
template <class T>
struct Node
{
T data;
Node *next;
};
template <class T>
class LinkList
{
private:
Node<T> *Head;
public:
LinkList();
void CreateCandidate(int n); //创建候选人名单
void CreateList(int n); //创建链表存储选票
void ResearchList(int n,int m); //统计票数
};
template <class T>
LinkList<T>::LinkList()
{
Head=new Node<T>;
Head->next=NULL;
}
template <class T>
void LinkList<T>::CreateCandidate(int n)
{
int i;
cout<<"*****************选票统计系统*****************"<<endl;
cout<<"请输入选手名单:"<<endl;
for(i=1;i<=n;i++)
{
string str;
cin>>str;
cout<<i<<"."<<str<<"\t";
}
cout<<endl;
}
template<class T>
void LinkList<T>::CreateList(int m)
{
Node<T> *p,*s;
p=Head;
cout<<"请依次输入选票结果:"<<endl;
for(int i=1;i<=m;i++)
{
s=new Node<T>;
cin>>s->data;
s->next=p->next;
p->next=s;
p=s;
}
cout<<"成功!"<<endl;
}
template<class T>
void LinkList<T>::ResearchList(int n,int m) {
Node<T> *q;
q=Head->next;
int l=0;
for(int i=1;i<=m;i++)
{
if(q->data==n)
{
l++;
// cout<<l<<endl;
}
q=q->next;
}
cout<<n<<"号选手总得票为:"<<l<<endl; }
void main()
{
int n,m;
LinkList<int> L;
//system("cls");
cout<<"请确认候选人人数以及总票数:";
cin>>n>>m;
L.CreateCandidate(n);
L.CreateList(m);
for(int i=1;i<=n;i++)
{
L.ResearchList(i,m);
//cout<<i<<endl;
}
}运行结果
4.4调试分析
由于候选人数不确定,所以要根据输入的候选人人数动态建立数组来存放得票情况。
在动态建立单链表的过程中系统出现过内存分配错误的问题,所以在建立链表时要保证尾节点的指针域始终为空,另设一个指针始终指向插入的节点,为下一个节点的插入做准备。
创建单链表的函数返回头节点的地址,所以函数类型为指针类型。
4.5用户使用说明
用户进入界面后,先输入候选人数,在输入要投票数,接着开始投票,依次输入。