提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
目录
一、中国计算机设计大赛赛事统计
(一)、问题描述
参加计算机设计大赛的n个学校编号为1~n,赛事分成m个项目,项目的编号为1~m.比赛获奖按照得分降序,取前三名,写一个统计程序产生各种成绩单和得分报表。
(二)、基本要求
1、每个比赛项目至少有10支参赛队;每个学校最多有6支队伍参赛;
2、能统计各学校的总分;
3、可以按照学校编号或名称,学校的总分、各项目的总分排序输出;
4、可以按学校编号查询学校某个项目的获奖情况;可以按项目编号查询取得前三名的学校;
5、数据存入文件并能随时查询
(三)、设计要求
1、输入数据形式和范围:可以输入学校的名称,赛事项目的名称。
2、输出形式:有中文提示,各学校分数为整数
3、界面要求:交互设计要合理,每个功能可以设立菜单,根据提示,可以完成相关功能的要求。
4、存储结构:学生自己根据系统功能要求自己设计,但是赛事相关数据要存储在文件中。
(四)、测试数据
要求使用全部合法数据,整体非法数据,局部非法数据。进行程序测试,以保证程序的稳定。
(五)、实现提示
假设3<赛事项目数量<=10,学校名称长度不超过20个字符。每个赛事结束时,将其编号、名称输入,并依次输入参赛学校编号、学校名称和成绩。
(六)问题分析和概要设计
1、问题分析
(1)、赛事相关数据内容自定义设置
(2)、交互式界面设置
(3)、选取合适的存储结构
(4)、统计总分功能
(5)、数据信息查询
2、概要逻辑结构设计
(1)、存储结构设计
typedef struct itemnode
{
int item[m0+5][n0+1];
}itemnode;
(2)、初始化信息
printf("输入信息\n");
printf("输入学校个数(至少三个):");
scanf("%d",&n);
printf("项目个数(至少三个):");
scanf("%d",&m);
int c;
int i,j;
struct itemnode a;
for(i=1;i<n+1;i++)
{
printf("请输入第%d个学校编号:",i);
scanf("%d",&a.item[0][i]);
printf("\n");
}
for(j=1;j<m+1;j++)
{
printf("请输入第%d个项目编号:",j);
scanf("%d",&a.item[j][0]);
printf("\n");
}
for(i=1;i<n+1;i++)
{
for(j=1;j<m+1;j++)
{
printf("请输入第%d个学校第%d个项目成绩:",i,j);
scanf("%d",&a.item[j][i]);
printf("\n");
}
}
for(i=1;i<n+1;i++)
{
a.item[m+1][i]=0;
a.item[m+2][i]=0;
a.item[m+3][i]=0;
a.item[m+4][i]=0;
}
二、校园导游咨询系统
(一)、问题描述
设计一个校园导游程序,为来访的客人提供各种信息查询服务。
(二)、基本要求
1、设计你所在学校的校园平面图,所含景点不少于10个.以图中顶点表示校内各景点,存放景点名称、代号、简介 等信息;以边表示路径,存放路径长度等相关信息。
2、为来访客人提供图中任意景点相关信息的查询。
3、为来访客人提供图中任意景点的问路查询,即查询任意两个景点之间的一条最短的简单路径。
(三)、测试数据
以江苏科技大学长山校区为例。
(四)、实现提示
一般情况下,校园的道路是双向通行的,可设校园平面图是一个无向网.顶点和边均含有相关信息.
(五)、问题分析和概要设计
1、问题分析
(1)、 根据学校地图,自我设置景点与对应信息,同时粗略的画出无向图。
(2)、选取合适的存储结构
(3)、初始化信息
(4)、设计信息查询功能函数
(5)、设计输出函数与交互式界面
2、概要逻辑结构设计
(1)、无向图绘画
(图三:无向图)
(2)、存储结构的设计实现
建立一个顶点结构体。在类中再建立一个顶点表(总的记录各顶点信息),一个邻接矩阵(表示各个顶点之间关系)。
struct ver //顶点的结构体
{
char code;
string name;
string intro;
};
class Graph
{
ver* VerticesList; // 顶点表
int** matrix; // 邻接矩阵
};
(3)、邻接矩阵绘制
(4)、模块设计
(表一)
Graph(); | 初始化 |
bool insertVertex(char code, string name, string intro); | 插入一个顶点信息在顶点集 |
bool insertEdge(int v1, int v2, int cost); | 插入一个边的信息在邻接矩阵 |
int Location(char code); | 用于判断查询信息时输入的异常 |
void information(int i); | 输出顶点表示位置的简介 |
void Show(); | 显示当前全部可查询区域 |
void InformationService(); | 地点相关信息查询 |
void ShortestPath(int v); | Dijkstra求最短路径 |
void PrintShortest(int v, int x); | 输出最短路径和距离 |
void ShorestService(); | 两地最短路径信息查询 |
(5)、信息预制
bool Graph::insertVertex(char code, string name, string introduction)
{
if (numVertices == maxVertices)
return false;
VerticesList[numVertices].code = code;
VerticesList[numVertices].name = name;
VerticesList[numVertices].intro = introduction;
numVertices++;
return true;
};
bool Graph::insertEdge(int v1, int v2, int distance)
{
if (v1 > -1 && v1<numVertices && v2>-1 && v2 < numVertices)
{
matrix[v1][v2] = matrix[v2][v1] = distance;
numEdges++;
return true;
}
else
return false;
};
Graph::Graph()
{
numVertices = 0;
numEdges = 0;
VerticesList = new ver[maxVertices]; // 顶点表
matrix = (int**) new int* [maxVertices]; // 邻接矩阵
for (int i = 0; i < maxVertices; i++)
matrix[i] = new int[maxVertices];
for (int i = 0; i < maxVertices; i++)
for (int j = 0; j < maxVertices; j++)
matrix[i][j] = (i == j) ? 0 : maxValue; // 邻接矩阵主对角线元素为0;顶点对间无边则权重无穷大
insertVertex('1', "校门(北门)", "北门正对海韵湖,北门前就是前往梦溪的校车学生上车点。");
insertVertex('2', "海韵胡", "海韵胡风景绮丽,也是大鹅的驻地。");
insertVertex('3', "计算机学院楼", "计算机学院楼,一看到这个楼就想起那写不完的无边无尽的实验报告。");
insertVertex('4', "文理大楼", "文理大楼是学校的标志性建筑,宣传册、录取通知书上都有它,门面担当爱了爱了。");
insertVertex('5', "经世楼", "经世楼紧靠明德楼,也称13号楼,夜间自习长期征用。");
insertVertex('6', "明德楼", "明德楼紧靠经世楼,也称14号楼,夜间自习长期征用。");
insertVertex('7', "校门(西门)", "西门,平时不开,隔着铁栏杆就是小吃街驻地,好耶!");
insertVertex('8', "西苑食堂", "西苑食堂带有船舶主题特色餐厅,面夫子早餐店超棒。");
insertVertex('9', "东苑食堂", "东苑食堂带有蚕桑主题特色餐厅,蛋糕店的小蛋糕超棒。");
insertVertex('0', "西操场", "西操场是夜间玩狼人杀最有氛围感的地方!别忘了带上准备好的小夜灯哟。 ");
insertEdge(0, 1, 100);
insertEdge(1, 2, 100);
insertEdge(0, 2, 200);
insertEdge(1, 3, 200);
insertEdge(2, 3, 300);
insertEdge(2, 6, 700);
insertEdge(3, 4, 200);
insertEdge(4, 5, 50);
insertEdge(4, 6, 200);
insertEdge(5, 7, 300);
insertEdge(6, 7, 500);
insertEdge(7, 9, 300);
insertEdge(8, 9, 800);
insertEdge(1, 8, 500);
insertEdge(4, 8, 900);
insertEdge(7, 8, 1000);
};
(6)、Dijkstra算法求最短路径
void Graph::ShortestPath(int v)//参考Dijkstra迪杰斯特拉算法
{
int n = numVertices;
dist = new int[n];//赋值
path = new int[n];
bool* S = new bool[n]; //顶点集存放最短路径
int i, j, k, w, min;
for (i = 0; i < n; i++)
{
dist[i] = matrix[v][i];//数组初始化
S[i] = false;
if (i != v && dist[i] < maxValue)
path[i] = v;
else
path[i] = -1;
}
S[v] = true; //顶点加入顶点集
dist[v] = 0;
for (i = 0; i < n - 1; i++)
{
min = maxValue;
int u = v; //选择最短路径的顶点u
for (j = 0; j < n; j++)
if (S[j] == false && dist[j] < min)
{
u = j;
min = dist[j];
}
S[u] = true;//顶点u加入集合S
for (k = 0; k < n; k++) //修改
{
w = matrix[u][k];
if (S[k] == false && w < maxValue && dist[u] + w < dist[k])//顶点k未加入S,且绕过u可以缩短路径
{
dist[k] = dist[u] + w;
path[k] = u; //修改到k的最短路径
}
}
}
};
(六)、主要功能函数实现及主函数
int Graph::Location(char code)
{
for (int i = 0; i < numVertices; i++)
if (VerticesList[i].code == code)
return i;
return -1;
};
void Graph::information(int i)
{
cout << " "<< "简介:" << VerticesList[i].INFORMATION << endl;
};
void Graph::InformationService()
{
int i;
char code;
while (1)
{
system("cls");
Show();
cout << " 请输入要查询的地点编号(输入#退出):";
cin >> code;
if (code == '#')
break;
i = Location(code);
if (i == -1)//判断输入异常
{
cout << " 输入错误,请重新输入" << endl;
}
else
{
information(i);
cout << " 按回车键继续";
getchar();
getchar();
}
}
};
void Graph::PrintShortest(int v, int x)
{
int a, b, n;
n = numVertices;
int* d = new int[n];
{
a = x;
b = 0;
while (a != v)
{
d[b++] = a;
a = path[a];
}
cout << VerticesList[v].name << "到" << VerticesList[x].name << "的最短路径为:" << endl<< VerticesList[v].name;
while (b > 0)
{
cout << "-->" << VerticesList[d[--b]].name;
}
cout << endl << " 最短路径长度为:" << dist[x] << endl;
}
delete[] d;
};
void Graph::ShorestService()
{
system("cls");
Show();
int v1, v2;
char code1, code2;
cout << " 编号如上图,请输入您要查询的两个地点的编号:" << endl;
cout << " 起始地点:";
cin >> code1;
cout << " 终止地点:";
cin >> code2;
while (1)
{
v1 = Location(code1);//确认输入信息正确是否
v2 = Location(code2);
if (v1 == -1 || v2 == -1)
{
cout << " 输入错误,请重新输入" << endl;
cout << " 起始地点:";
cin >> code1;
cout << " 终止地点:";
cin >> code2;
}
else
{
ShortestPath(v1);
PrintShortest(v1, v2);
break;
}
}
cout << " 按回车键继续";
getchar();
getchar();
};
void Graph::Show()
{
for (int i = 0; i < 8; i++)
cout << endl;
cout << " ______________________________________________________________________________________________________________" << endl;
cout << " | 可选择区域如下 |" << endl;
for (int i = 1; i <= numVertices; i++)
{
cout <<" | "<< VerticesList[i - 1].code<<" "<< VerticesList[i - 1].name << endl;
}
cout << " |____________________________________________________________________________________________________________|" << endl;
};
int main()
{
Graph graph;
string Choice;
int choice;
while (1)
{
system("cls");
for (int i = 0; i < 8; i++)
cout << endl;
cout << " ______________________________________________________________________________________________________________" << endl;
cout << " | 欢迎使用长山校区导游咨询系统 |" << endl;
cout << " | 输入1 查询区域信息 |" << endl;
cout << " | 输入2 查询两地点间最短路径 |" << endl;
cout << " | 输入0 退出系统 |" << endl;
cout << " |____________________________________________________________________________________________________________|" << endl;
cout << " 请输入您要执行功能的编号:";
cin >> Choice;
if (Choice.length() == 1)
choice = (Choice.at(0) - 48);//字符串转整型
else
choice = 3;
if (choice < 0 || choice>2)
{
cout << " 按回车键继续,输入错误," << endl;
getchar();//当前界面停留,等待下一步操作
getchar();
}
switch (choice)
{
case 1:
graph.InformationService();
break;
case 2:
graph.ShorestService();
break;
case 0:
system("cls");
for (int i = 0; i < 11; i++)
cout << endl;
cout << " ____________________________________________________OVER______________________________________________________" << endl;
for (int i = 0; i < 11; i++)
cout << endl;
return 0;
}
}
return 0;
}
(七)、程序实现结果
三、算术表达式求解
(一)、问题描述
设计一个简单的算术表达式计算器。
(二)、基本要求
实现标准整数类型的四则运算表达式的求值(包含括号,可多层嵌入)。
(三)、测试数据
(30+2*70)/3-12*3
5+(9*(62-37)+15)*6
(四)、问题分析和概要设计
1、问题分析
(1)、 需要从键盘输入任意算术表达式,并判断算数表达式输入正确性,对于错误表达式给出提示
(2)、 选取数据的存储结构
(3)、 进行运算
(4)、 输出对应结果
2、概要逻辑结构设计
(1)、输入设计
键盘输入表达式,在函数中判断输入表达式的每一个字符,如果是运算符,将这些字符放入操作符栈, 并比较优先级, 判断是否进行运算。如果读入的字符为“0‟到“9‟之间的数字, 用字符相减转化为整型, 然后将转化后的整型转化为 ASCII 形式压入操作数栈中。
(2)、存储结构的设计实现
考虑表达式中有无括号以及左右括号之分,同时运算符有不同优先级, 因此一个算数表达式不能总按顺序执行,选择用栈来实现运算符优先级,完成算术表达式求解。
设置两个栈:一个操作数栈 ,另一个为操作符栈。置操作数栈初始为空栈,表达式结束符“#”为操作符栈地栈底元素。
typedef struct
{
int data[SIZE];//长度数组
int top;
}Stack;
Stack StackR, StackD;// 定义两个栈分别存放运算符和操作数
(3)、优先级比较设计实现
运算符 | + | - | * | / | ( | ) | # |
栈内操作符优先级 | 2 | 2 | 3 | 3 | 1 | 4 | 0 |
栈外操作符优先级 | 2 | 2 | 3 | 3 | 4 | 1 | 0 |
char Compare(char op, char c)//比较优先级
{
char winner=op;//存放优先级高的运算符
if (op == '(' && c == ')' || op == '#' && c == '#')
winner = '=';
else if (op == '+' || op == '-')
switch (c)
{
case '+':
case '-':
case ')':
case '#':
winner = '>';
break;
case '*':
case '/':
case '(':
winner = '<';
}
else if (op == '*' || op == '/')
switch (c)
{
case '+':
case '-':
case '*':
case '/':
case ')':
case '#':
winner = '>';
break;
case '(':
winner = '<';
}
else if (op == '(')
switch (c)
{
case '+':
case '-':
case '*':
case '/':
case '(':
winner = '<';
break;
case '#':
cout << "Error!没有右括号!" << endl;
winner = '0';
}
else if (op == ')')
switch (c)
{
case '+':
case '-':
case '*':
case '/':
case '#':
winner = '>';
break;
case '(':
cout << "Error!括号匹配错误!" << endl;
winner = '0';
}
else if (op == '#')
switch (c)
{
case '+':
case '-':
case '*':
case '/':
case '(':
winner = '<';
break;
case ')':
cout << "Error!没有左括号!" << endl;
winner = '0';
}
return winner;
}
(4)、模块设计
依次读入表达式中每个字符,若为操作数, 则进操作数栈;若是运算符, 则与操作符栈中栈顶运算符比较优先级后做相应操作,若当前操作符大于操作符栈中栈顶, 则当前操作符入栈; 否则, 操作数栈地栈顶元素、 次栈顶元素出栈, 同时操作符栈中栈顶元素也出栈, 运算并将结果压入操作数栈, 直至整个表达式求值完毕,需要功能函数如下表。
void stack(Stack* s); | 初始化 |
int Empty(Stack* s); | 判断是否为空栈 |
void Push(Stack* s, int ); | 压栈 |
int Pop(Stack* s); | 出栈 |
int GetTop(Stack* s); | 取栈顶元素 |
int isoperator(char ch); | 判断输入符号是否为运算符或左右括号 |
int iswhitespace(char ch) | 判断输入符号是否为空格、制表符或换行符 |
char Compare(char op, char c); | 比较优先级 |
int calculation(int a, char ch, int b); | 计算结果 |
int Overall(char ch); | 总的求解 |
(五)、主要功能函数实现及主函数
void getstack(Stack* s) //初始化栈
{
s->top = -1;
}
int Empty(Stack* s)//判断空栈
{
if (s->top == -1)
return 1;
else
return 0;
}
void Push(Stack* s, int x) //压栈
{
if (s->top == SIZE1-1)
{
cout << "表达式有误,栈上溢!计算出错误结果。";
}
else
{
s->top++;
s->data[s->top] = x;
}
}
int Pop(Stack* s)// 出栈
{
int e;
if (s->top==-1)
{
cout << "表达式有误,栈下溢!计算出错误结果。";
}
else
{
e = s->data[s->top];
s->top--;
return e;
}
}
int GetTop(Stack* s) //取栈顶元素
{
if (s->top == -1)
{
cout << "表达式有误,栈下溢!计算出错误结果。";
}
else
return s->data[s->top ];
}
int isoperator(char ch) //判断 ch 是否为操作符
{
if (ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '(' || ch == ')'||ch=='#')
return 1;
return 0;
}
int iswhitespace(char ch)//判断 ch 是否为空格、制表符或换行符,是返回 1 否则返回 0
{
if (ch == ' ' || ch == '\t' || ch == '\n')
return 1;
return 0;
}
int calculation(int a, char ch, int b)//计算
{
int s;
int A = a;
int B = b; //把字符变为 ascii 码对应数字
switch (ch)
{
case '+':
s = A + B;
break;
case '-':
s = B - A;
break;
case '*':
s = A * B;
break;
case '/':
if (A != 0)
{
s = B / A;
}
else
{
cout<<"Error!除数为 0"<<endl;
}
}
return (s + '0'); //将运算结果转化为 ascii 码入栈
}
int Overall(char c[SIZE2]) // 总的求解
{
int a, b, i = 0, s = 0;
char r;
getstack(&StackR);
getstack(&StackD);
Push(&StackR, '#');
while (c[i] != '#' || GetTop(&StackR) != '#')
{
if (isoperator(c[i])==0) //判断读入字符是否为操作数
{
if (c[i] >= '0' && c[i] <= '9')
{
s += c[i] - '0';
while (!isoperator(c[++i])) //下一个字符如果不是运算符,则为多位数
{
s *= 10;
s += c[i] - '0';
}
Push(&StackD, s + '0'); //将整型转化为 ascii 地形式入栈
s = 0; //归零循环
}
else
{
cout<<"输入表达式有误!"<<endl;
return -1;
}
}
else
switch (Compare(GetTop(&StackR), c[i]))
{
case '<': //当前运算符入栈
Push(&StackR, c[i]);
i++;
break;
case '=':
Pop(&StackR);
i++;
break;
case '>': //栈顶优先级高,出栈进行运算
r = Pop(&StackR);
a = Pop(&StackD) - '0';
b = Pop(&StackD) - '0';
Push(&StackD, calculation(a, r, b));
break;
case '0':
return -1;
}
}
return (GetTop(&StackD) - '0'); // 输出栈顶,也就是运算结果
}
int main()//主函数
{
cout<<"______________________计算器开始______________________"<< endl;
o:
int v,N;
char ch[SIZE2];
int num = 0;
cout << "请输入正确的算数表达式, 无需输入等于号,并以#结束。" << endl;
while (1)
{
cin >>ch[num];
if (ch[num] == '#')
{
cout << "输入结束" << endl;
break;
}
else
{
num++;
}
}
v = Overall(ch);
if (v != -1)
cout << "表达式地计算结果为:" << v << endl;
else
{
cout << "是否重新输入表达式?" << endl;
oo:
cout<<"请输入正确的数字。输入0继续输入,输入1退出计算器。" << endl;
cin >> N;
if(N==0)
goto o;
else if (N != 1&&N!=0)
{
goto oo;
}
}
cout << "______________________计算器结束______________________" << endl;
return 0;
}