为什么要开设数据结构课程设计
课程设计一直是学习数据结构的必要内容,也是掌握数据结构和C语言的最快最重要的方式之一,有利于掌握数据结构与算法的设计方法,具备初步的独立分析和设计能力,每个学校开设数据结构课程时都会附带有数据结构课程设计任务。
课程设计题目:算术表达式的求解
设计要求:
设计一个算术表达式求解的程序,能重复地执行以下操作,直到选择退出为止。
程序功能包括:
(1)从键盘输入要求解的算术表达式(表达式必须包括加减乘除和括号);
(2)采用栈结构进行算术表达式的求解过程(不用栈结构验收不合格);
(3)能够判断算术表达式正确与否;
(4)对于错误表达式给出提示;
(5)对于正确的表达式给出最后的结果;
任务概述
在本程序中,表达式由运算符和数字组成,运算符具有不同的优先级,又要考虑括号,因此,不能严格从左到右进行,由此想到运用两个链栈分别进行存放运算符和数字,链栈的定义如下:
typedef struct SqNode{char data;struct SqNode *next;}SqNode,*SqStack;
系统功能模块结构图
程序运行数据及其结果
数据通过键盘输入运算符和0-9的数字,程序可正常运行,正常计算,如遇输入错误可进行报错,返回进行重新输入。
第一次输入1+5*(2+1)#输入合法,计算结果为16正确;
第二次输入5+2输入不合法,报错误。
程序源码
#include<stdio.h>#include<stdlib.h>#define OK 1#define ERROR 0#define OVERFLOW -2typedef struct SqNode{char data;struct SqNode *next;}SqNode,*SqStack;int InitStack(SqStack &S) {S=NULL;return OK;}int Push(SqStack &S, char e) {//入栈 SqNode *p =(SqStack)malloc(sizeof(SqNode));if (!p) {return OVERFLOW;//溢出 }p->data=e;p->next=S;S=p;return OK;}int Pop(SqStack &S,char &e) {//出栈 SqNode *p;if (!S)return ERROR;//空栈 e=S->data;p=S;S=S->next;free(p);return OK;}int GetTop(SqStack &S) {//获得栈顶元素值 if (!S)return ERROR;//空栈 return S->data;}int In(char ch) {//判断ch是否为运算符if(ch=='+'||ch=='-'||ch=='#'||ch=='*'||ch=='/'||ch=='('||ch==')')return 1;else return 0;}int Out(char ch){//判断ch是否为数字 if(ch=='1'||ch=='2'||ch=='3'||ch=='4'||ch=='5'||ch=='6'||ch=='7'||ch=='8'||ch=='9'||ch=='0')return 1;else return 0;}char Precede(char theta1, char theta2) {//判断运算符优先级if ((theta1=='('&&theta2==')')||(theta1=='#'&&theta2=='#')){return '=';} else if (theta1=='('||theta1=='#'||theta2=='('||(theta1=='+'||theta1=='-')&&(theta2=='*'||theta2=='/')){return '<';} elsereturn '>';}char Operate(char first, char theta, char second) {//计算两数运算结果switch (theta) {case '+':return (first-'0'/*得到数字*/)+(second-'0')+48;//得到char case '-':return (first-'0')-(second-'0')+48;case '*':return (first-'0')*(second-'0')+48;case '/':return (first-'0')/(second-'0')+48;}return 0;}//表达式求值char EvaluateExpression() {SqStack OPTR,OPND;char ch,theta,a,b,x,top;InitStack(OPND); InitStack(OPTR); Push(OPTR,'#'); scanf("%c",&ch);while(ch!='#'||(GetTop(OPTR)!='#')) {if(Out(ch))//如果是数字 {Push(OPND,ch);scanf("%c",&ch);} else if(In(ch))//如果是运算符 switch (Precede(GetTop(OPTR),ch)){case '<':Push(OPTR,ch);//入栈 scanf("%c",&ch); break;case '=': Pop(OPTR,x);//出栈 scanf("%c",&ch); break;case '>':Pop(OPTR,theta); Pop(OPND,b);Pop(OPND,a); Push(OPND,Operate(a,theta,b)); break;} else {printf("输入错误,请重新输入!\n");ch='0';continue;}} return GetTop(OPND); //OPND栈顶元素即为表达式求值结果}int menu() {int c;printf("表达式求解程序:\n");printf("1.开始计算\n");printf("0.退出程序\n");printf("请选择:");scanf("%d",&c);getchar();return c;}int main() {while (1) {switch (menu()) {case 1: {printf("请输入表达式(以#结束):\n"); char x = EvaluateExpression();//表达式求值printf("计算结果为:");printf("%d\n",x-'0'); printf("******************************************\n\n");}break;case 0:printf("退出成功\n");exit(0);default:break;}}return 0;}
课程设计心得
通过本次课程设计我发现,在学习过程中不能只研究理论知识,必须经常进行实践操作,因为在实际操作中会遇到很多问题是理论学习中考虑不到的,在不断尝试和修改过程中,才会更深入的理解和掌握c语言和数据结构的内容。在设计程序时,不光要写好各个程序,还要注意它们之间的联系,因为每个函数都不是独立的,稍微有一点错误就会导致整个程序错误,而且还不容易找到错误的位置。在此次设计中,有一个if语句的条件正确执行后却是错误的,在询问老师后经过不断的修改才找到了错误的根源,并不是if语句附近的代码,而是在main函数中缺少一个必要的语句,由此看来程序设计中最重要的是瞻前顾后的能力,要有一定的分析能力才能更好的完善程序。这次程序设计让我发现,我的c语言基础还是比较扎实的,但是数据结构部分对我还是稍微有些难度的,在设计函数的时候比较困难,今后要在这方面多强化一些。