个人学习笔记001(数据结构课设预习报告)

本文详细介绍了三项计算机设计任务:中国计算机设计大赛的赛事统计系统,校园导游咨询系统的实现,以及算术表达式的求解。在赛事统计系统中,要求包括学校总分统计、查询功能和数据存储;导游系统涉及景点信息查询和最短路径计算;算术表达式求解实现了整数四则运算和括号处理。所有项目都包含了设计要求、测试数据、实现提示和逻辑结构设计,以及程序实现结果。
摘要由CSDN通过智能技术生成

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

目录

一、中国计算机设计大赛赛事统计

(一)、问题描述

(二)、基本要求

(三)、设计要求

(四)、测试数据

(五)、实现提示

(六)问题分析和概要设计

二、校园导游咨询系统

(一)、问题描述

(二)、基本要求

(三)、测试数据

(四)、实现提示

(五)、问题分析和概要设计

(六)、主要功能函数实现及主函数

(七)、程序实现结果

三、算术表达式求解

(一)、问题描述

(二)、基本要求

(三)、测试数据

(四)、问题分析和概要设计

(五)、主要功能函数实现及主函数

(六)、程序实现结果


一、中国计算机设计大赛赛事统计

(一)、问题描述

参加计算机设计大赛的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)、优先级比较设计实现

运算符+-*/()#
栈内操作符优先级2233140
栈外操作符优先级2233410
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;
}

(六)、程序实现结果

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值