四川大学《数据结构与算法分析》课程设计报告-带括号的算术表达式
算术表达式的求解-数据结构课程设计报告
算术表达式的求解-数据结构课程设计报告课程设计报告题目:算术表达式求值一、需求分析 1、设计要求:给定一个算术表达式,通过程序求出最后的结果 1>、从键盘输入要求解的算术表达式; 2>、采用栈结构进行算术表达式的求解过程; 3>、能够判断算术表达式正确与否;4>、对于错误表达式给出提示;5>、对于正确的表达式给出最后的结果; 2、设计构想:为了实现算符优先算法使用两个工作栈,一个称作OPTR,以寄存运算符;另一个称作OPND,用以寄存操作数或运算结果。
在操作数和操作符入栈前,通过一个函数来判别,输入的是操作数还是操作符,操作数入OPND,操作符入OPTR。
在输入表达式的最后输入‘#’,设定‘#’的优先级最低,代表表达式输入结束。
在表达式输入过程中,遇操作数则直接入栈,遇到运算符则与栈顶运算符比较优先级,若当前运算符优先级高,则当前运算符入栈,扫描下一符号;否则栈顶运算符出栈,两操作数出栈,进行运算,所得结果入数栈,重新比较当前运算符与新栈顶运算符。
如此重复直到栈顶运算符与当前符号均为‘#’,运算结束。
二、概要设计1、本程序包含的模块:栈模块——实现栈抽象数据类型运算模块——实现数据表达式的运算主程序模块算术运算式的求解栈模块主函数模块main 运算模块定义栈结构初始化栈出栈入栈取栈顶元素判断输入字符类型判断符号优先级基础运算函数运算函数三、详细设计栈模块1、定义栈结构 struct Sqstack{elemtype *top;//栈顶元素 elemtype *base; //栈底元素 int stacksize;//栈的大小 };2、栈的基本操作①初始化栈status initstack(struct Sqstack &s) {=(elemtype *)malloc(stack_size*sizeof(elemtype)); if(!) return OVERFLOW; =;=stack_size; return OK; } ②入栈status push(struct Sqstack &s,elemtype e) {if(>=) {=(elemtype*)realloc(,(+stack_increasement)*sizeof(elemtype));if(! ) return OVERFLOW; =+; +=stack_increasement; } * ++=e; return OK; } ③出栈elemtype pop(struct Sqstack &s) {elemtype e; if(= =) return ERROR; e=*--;return e; }④取栈顶元素elemtype gettop(struct Sqstack &s) {elemtype e; if(==) return ERROR; e=* ; return e; } 运算模块1、判断输入字符c是否为操作符:若是,则返回1;否则,返回0 int In(int c) {char p[10]=\ int i=0;while(p[i]!='\\0') {if(p[i]==c) return 1;i++; } return 0; }2、判断运算符的优先级char precede(char top,char c)//该函数为判断当前运算符与前一个运算符的优先级,前一个运算符高于或等于当前运算符的优先级则返回‘>’,前一个运算符小于当前运算符的优先级则返‘'; break; case '+': case '-':if(top=='#'||top=='(')result=''; break; case '*': case '/':if(top=='*'||top=='/'||top=='^') result='>'; elseresult=''; elseresult=''; break;case '(': result='': theta=pop(optr); b=pop(opnd); a=pop(opnd); push(opnd,operate(a,theta,b)); break;// 若当前操作符的优先级低于操作符栈的栈顶元素,则将操作符栈栈顶元素出栈,并将操作数栈的栈顶两个元素出栈,计算两个元素间以操作符栈栈顶元素为运算符的数学运算}//switch }//if}//whilereturn pop(opnd); }主程序模块1、main函数void main(int argc,char *argv) {struct Sqstack opnd; //操作数栈 struct Sqstack optr;//操作符栈initstack(opdn); initstack(optr); elemtype result;printf(\ printf(\算术运算式的求解\printf(\ printf(\请输入算术运算表达式(以'#'结尾):\\n\ printf(\result=evaluate(opnd,optr);printf(\printf(\运算的结果是 :\\n \\n%d\\n\printf(\}四、调试分析 1、测试结果1> 测试数据:3+7*2-1# 测试结果:2> 测试数据:(3+7)*2-1# 测试结果:3> 测试数据: 1/0# 测试结果:2、程序时间复杂度为O;3、设计中出现的问题:在开始的设计中没有注意除数不能为0 ,后来加入if(b==0) {printf(\分母为0,the result is error\\n\ result=0; } elseresult=a/b;break;来判断除数是否为0 4、算法改进:1>输入的操作数和操作码于是字符串类型的,在原设计中实现的操作都是对个位数实现的,实用性不大,故在后来的设计中,通过一个标志flag实现了标志操作数的连续输入的判别,继而实现了多位数的表达式运算2>开始只实现了加、减、乘、除及带小括号的数学运算,考虑到实用性,在后来的设计中引入pow函数,实现了乘方的运算,调整结果如下:3>最初设计的运行界面过于单调,不够友好,改进时加入一些*调整调整结果如下:五、课程设计总结本学期是我第一次接触课程设计,发现了很多学习上的问题,也有很多收获。
川大数据结构课程设计
川大数据结构课程设计一、课程目标知识目标:1. 学生能够理解数据结构的基本概念,掌握线性表、栈、队列、树和图等常见数据结构的特点与应用。
2. 学生能够描述不同数据结构在解决实际问题中的优势与局限,并分析其时间复杂度和空间复杂度。
3. 学生能够运用所学知识设计简单算法,解决实际问题。
技能目标:1. 学生能够运用C/C++等编程语言实现常见数据结构及其基本操作。
2. 学生能够运用数据结构知识对实际问题进行分析,选择合适的数据结构并编写相应算法。
3. 学生能够运用调试工具和技巧,优化程序性能,提高代码质量。
情感态度价值观目标:1. 学生通过学习数据结构,培养严谨的逻辑思维和问题分析能力。
2. 学生能够认识到数据结构在实际应用中的重要性,激发对计算机科学的兴趣和热情。
3. 学生在团队协作和讨论中,培养良好的沟通能力和合作精神。
课程性质:本课程为计算机科学与技术专业的基础课程,旨在帮助学生掌握数据结构的基本原理和方法,为后续算法分析与设计、软件工程等课程打下基础。
学生特点:大一、大二学生,具备一定的编程基础,对数据结构有一定了解,但尚不深入。
教学要求:注重理论与实践相结合,通过案例分析和实际编程,使学生更好地理解和掌握数据结构知识。
同时,注重培养学生的逻辑思维和问题解决能力,提高其计算机素养。
二、教学内容1. 线性表:介绍线性表的定义、特点和基本操作,包括顺序存储和链式存储结构,分析其优缺点及适用场景。
教材章节:第2章 线性表内容安排:2学时2. 栈与队列:讲解栈和队列的基本概念、操作及应用,分析其时间复杂度和空间复杂度。
教材章节:第3章 栈和队列内容安排:2学时3. 树与二叉树:阐述树和二叉树的基本概念、性质、存储结构及遍历方法,介绍哈夫曼树、平衡二叉树等特殊树及其应用。
教材章节:第4章 树和二叉树内容安排:4学时4. 图:介绍图的定义、存储结构、遍历方法以及最小生成树、最短路径等算法。
教材章节:第5章 图内容安排:4学时5. 排序算法:讲解常见排序算法,如冒泡排序、插入排序、快速排序等,分析其时间复杂度和稳定性。
算术表达式的求解-数据结构课程设计报告
算术表达式的求解-数据结构课程设计报告数据结构》课程设计报告书题目:算术表达式的求解系别:计算机科学与应用数据结构课程设计目录一、需求分析1、设计要求:本程序需要实现对算术表达式的求解功能,可以支持基本的四则运算,包括加、减、乘、除,同时还需要支持括号的使用。
2、设计构想:我们将使用栈来实现算术表达式的求解。
具体地,我们将把中缀表达式转换为后缀表达式,然后再利用栈来求解后缀表达式。
二、概要设计1、本程序包含的模块:本程序包含两个模块:中缀表达式转后缀表达式模块和后缀表达式求解模块。
三、详细设计1、定义栈结构我们定义一个栈结构,用来存储算术表达式中的运算符和操作数。
具体地,栈中的每个元素都包含两个属性:元素的值和元素的类型。
元素的值可以是一个数字或一个运算符,元素的类型可以是数字或运算符。
我们使用一个数组来实现栈的结构。
为了方便起见,我们还需要定义一些基本的栈操作,如入栈、出栈、判断栈是否为空等。
2、栈的基本操作栈是一种常见的数据结构,具有后进先出(LIFO)的特点。
栈的基本操作包括初始化栈、入栈、出栈、取栈顶元素和运算模块。
1) 初始化栈初始化栈是指将栈的各项属性设置为初始状态。
通常包括将栈顶指针设为-1,表示栈为空。
2) 入栈入栈是指将元素压入栈顶。
入栈操作需要将栈顶指针加1,并将元素存入栈顶位置。
3) 出栈出栈是指将栈顶元素弹出。
出栈操作需要将栈顶元素取出,并将栈顶指针减1.4) 取栈顶元素取栈顶元素是指获取栈顶元素的值,但不将其弹出。
取栈顶元素操作只需要返回栈顶元素的值即可。
5) 运算模块栈可以用于实现各种运算,例如中缀表达式的转换和计算、括号匹配等。
运算模块需要根据具体需求进行设计和实现。
3、判断运算符的优先级在进行中缀表达式的转换和计算时,需要判断运算符的优先级。
通常采用栈来实现这一功能。
具体实现方法是将运算符入栈,当遇到新的运算符时,将其与栈顶运算符进行比较,如果新运算符的优先级高于栈顶运算符,则将其入栈,否则将栈顶运算符弹出并输出,直到新运算符可以入栈为止。
数据结构课程设计-表达式求值【完整版】
XXXXXX大学《数据结构》课程设计报告班级:学号:姓名:指导老师:目录一算术表达式求值一、需求分析二、程序得主要功能三、程序运行平台四、数据结构五、算法及时间复杂度六、测试用例七、程序源代码二感想体会与总结算术表达式求值一、需求分析一个算术表达式就是由操作数(operand)、运算符(operator)与界限符(delimiter)组成得。
假设操作数就是正整数,运算符只含加减乘除等四种运算符,界限符有左右括号与表达式起始、结束符“#”,如:#(7+15)*(23—28/4)#。
引入表达式起始、结束符就是为了方便.编程利用“算符优先法”求算术表达式得值.二、程序得主要功能(1)从键盘读入一个合法得算术表达式,输出正确得结果。
(2)显示输入序列与栈得变化过程。
三、程序运行平台Visual C++6、0版本四、数据结构本程序得数据结构为栈。
(1)运算符栈部分:struct SqStack //定义栈{char *base; //栈底指针char *top; //栈顶指针intstacksize; //栈得长度};intInitStack (SqStack &s) //建立一个空栈S{if (!(s、base= (char *)malloc(50*sizeof(char))))exit(0);s、top=s、base;s、stacksize=50;return OK;}char GetTop(SqStack s,char &e) //运算符取栈顶元素{if (s、top==s、base) //栈为空得时候返回ERROR{ﻩ printf("运算符栈为空!\n");ﻩ return ERROR;}elsee=*(s、top-1); //栈不为空得时候用e做返回值,返回S得栈顶元素,并返回OK returnOK;}int Push(SqStack&s,char e) //运算符入栈{if (s、top—s、base >= s、stacksize)ﻩ{printf("运算符栈满!\n");ﻩs、base=(char*)realloc(s、base,(s、stacksize+5)*sizeof(char));//栈满得时候,追加5个存储空间if(!s、base)exit (OVERFLOW);s、top=s、base+s、stacksize;s、stacksize+=5;}ﻩ*(s、top)++=e;//把e入栈ﻩreturn OK;}int Pop(SqStack &s,char &e) //运算符出栈{if (s、top==s、base) //栈为空栈得时候,返回ERROR{printf("运算符栈为空!\n”);ﻩ return ERROR;}else{ﻩﻩe=*-—s、top;//栈不为空得时候用e做返回值,删除S得栈顶元素,并返回OK return OK;}}int StackTraverse(SqStack&s)//运算符栈得遍历{ﻩchar *t;ﻩt=s、base;ﻩif (s、top==s、base){ﻩ printf(”运算符栈为空!\n”); //栈为空栈得时候返回ERRORreturn ERROR;}while(t!=s、top){ﻩﻩprintf(" %c",*t); //栈不为空得时候依次取出栈内元素t++;ﻩ}return ERROR;}(2)数字栈部分:struct SqStackn//定义数栈{int *base; //栈底指针int*top; //栈顶指针int stacksize; //栈得长度};intInitStackn (SqStackn &s) //建立一个空栈S{s、base=(int*)malloc(50*sizeof(int));if(!s、base)exit(OVERFLOW);//存储分配失败s、top=s、base;s、stacksize=50;return OK;}int GetTopn(SqStackn s,int&e) //数栈取栈顶元素{if(s、top==s、base){printf("运算数栈为空!\n");//栈为空得时候返回ERRORﻩ return ERROR;}elseﻩe=*(s、top-1);//栈不为空得时候,用e作返回值,返回S得栈顶元素,并返回OKreturnOK;}int Pushn(SqStackn &s,int e) //数栈入栈{if(s、top—s、base>=s、stacksize){ﻩﻩprintf("运算数栈满!\n");//栈满得时候,追加5个存储空间ﻩs、base=(int*)realloc (s、base,(s、stacksize+5)*sizeof(int));if(!s、base) exit (OVERFLOW);ﻩs、top=s、base+s、stacksize;//插入元素e为新得栈顶元素s、stacksize+=5;}*(s、top)++=e; //栈顶指针变化returnOK;}int Popn(SqStackn &s,int &e)//数栈出栈{ﻩif (s、top==s、base){ﻩ printf("运算符栈为空!\n");//栈为空栈得视时候,返回ERRORﻩ return ERROR;ﻩ}else{ﻩﻩe=*—-s、top;//栈不空得时候,则删除S得栈顶元素,用e返回其值,并返回OK ﻩreturnOK;}}int StackTraversen(SqStackn &s)//数栈遍历{ﻩint*t;ﻩt=s、base ;ﻩif(s、top==s、base)ﻩ{printf("运算数栈为空!\n”);//栈为空栈得时候返回ERRORﻩ return ERROR;ﻩ}ﻩwhile(t!=s、top)ﻩ{printf(” %d”,*t); //栈不为空得时候依次输出t++;}return ERROR;}五、算法及时间复杂度1、算法:建立两个不同类型得空栈,先把一个‘#’压入运算符栈。
数据结构课程设计---括号匹配
数据结构课程设计---括号匹配⽬录1 问题描述 (2)1.1题⽬ (2)1.2问题 (2)1.3要求 (2)2 设计 (2)2.1存储结构设计 (2)2.2主要算法设计 (3)2.3测试⽤例及测试结果 (6)3 调试报告 (9)4 对设计和编码的讨论和分析 (20)4.1设计 (20)4.2对编码的讨论 (21)5 总结和体会 (22)附录⼀ (24)本科⽣课程设计成绩评定表................... 错误!未定义书签。
数据结构课程设计——判别括号配对1问题描述1.1题⽬:判别括号配对1.2问题:⼀个算术表达式含圆括号、中括号、花括号,且它们可任意嵌套使⽤。
写⼀程序,判断任⼀算术表达式中所含括号是否正确配对。
1.3要求:(1)表达式从键盘输⼊。
(2)利⽤栈求解此问题。
(3)测试⽤例⾃⼰设计。
2设计2.1存储结构设计题⽬要求利⽤栈来求解此问题,因此选择顺序栈作为存储结构,具体表⽰如下:#define STACK_INIT_SIZE 100#define STACKINCREMENT 10char *base;char *top;int stacksize;}SqStack;2.2主要算法设计2.2.1算法思想(1)⽂字描述从键盘输⼊⼀个表达式;逐个扫描表达式中的字符;当遇到左括号时,将左括号⼊栈;继续扫描,将此后遇到的第⼀个右括号与栈顶元素⽐较,若匹配,则栈顶元素出栈;否则,继续扫描;当整个表达式扫描完以后,判断栈内是否还有元素,若有,则括号不匹配;若栈为空,则括号配对成功;在括号配对不成功的情况下,利⽤栈顶栈底元素的差值,可以对左右括号数进⾏⽐较。
(2)流程图表⽰2.2.2算法void CharIsCorrect(char a[]){SqStack S;char e;int n,c;InitStack(S);//建⽴⼀个空栈n=strlen(a);//求表达式长度int d=0,b=0;for(int i=0;iif((a[i]=='(')||(a[i]=='[')||(a[i]=='{'))Push(S,a[i]);else{c=StackEmpty(S);if ((c==1)&&((a[i]==')')||(a[i]==']')||(a[i]=='}')))//栈为空且当前扫描的字符为右括号时,右括号多于左括号++b;else{e=GetTop(S);if (((a[i]==')')&&(e=='('))||((a[i]==']')&&(e=='['))||((a[i]=='}')&&(e=='{')))//括号匹配时满⾜的条件e=Pop(S);else if ((a[i]==')')||(a[i]==']')||(a[i]=='}'))++d;}}}//扫描字符串,左括号进栈,右括号出栈if(StackEmpty(S)==1&&(b==0)&&(d==0))cout<<"左右括号配对正确"<else cout<<"左右括号不匹配且左括号与右括号个数差为"<}2.3测试⽤例及测试结果(1)表达式不含除括号外其他字符,配对正确的情况:(2)表达式不含除括号外其他字符且左括号少于右括号的情况:(3)表达式含任意字符且左括号少于右括号的情况:(4)表达式含任意字符且左右括号个数相同但配对不成功的情况:(5)表达式仅含括号且括号个数相同单不匹配的情况:(6)表达式仅含括号且左括号对于右括号的情况:3调试报告1.本次课程设计,主要的调试过程在于对于判别函数的调试,但是除此之外,由于编译过程中发现了⼀些错误,对于栈的⼀些基本操作,以及main函数,也进⾏了调试,其中遇到的主要问题如下:(1)⼤⼩写出错(2)在写“判断栈是否为空”的操作时,将函数的类型标⽰符写错,导致了如下错误:解决办法:将“void”改为“int”后,能够正常运⾏。
四川大学网络学院-数据结构课程设计-参考答案
四川大学《数据结构》课程设计实验项目及内容提要(实验任选一个完成)
试读3页
数据结构实验报告
实验名称: Huffman编码(二叉树应用)
提交文档学生姓名:
提交文档学生学号:
同组成员名单:无
指导教师姓名:
指导教师评阅成绩:
指导教师评阅意见:
.
.
提交报告时间: 2020 年 3 月 26 日
目录
一、概述 (1)
二、系统分析 (1)
三、概要设计 (2)
四、详细设计 (4)
4.1 赫夫曼树的建立 (4)
4.1.1 选择选择parent 为0 且权值最小的两个根结点的算
法 (5)
4.1.2 统计字符串中字符的种类以及各类字符的个数 (7)
4.1.3构造赫夫曼树 (8)
4.2赫夫曼编码 (10)
4.2.1赫夫曼编码算法 (10)
4.2.2建立正文的编码文件 (11)
4.3代码文件的译码 (12)
五、运行与测试 (14)
六、总结与心得 (14)
参考文献................................. 错误!未定义书签。
附录..................................... 错误!未定义书签。
数据结构课程设计_带括号的算术表达式求值
素元层顶最的中栈回返 // ;)(daeHteG
XX
作操栈空清 // ;)(y tpmEekaM
计设程课析分法算与构结据数)++C( :称名程课
。出输的等果结行进数函 tuptuo 用 )4( 。算运的同不行进符作操
的数先优的同不。级先优定确�型类符作操断判则�符作操为取读果如 )3(
atad 进并数作操读 �)kcabtup.nic(流入输回返符字将则 �数作操为取读果如 )2(
;pmt eteled
;daeh=pm t* >melE<edoNkcatS
)LLUN=!daeh(elihw
{
)(ytpm EekaM di ov
XX
{
计设程课析分法算与构结据数)++C( :称名程课
;hc rahc
流入输空清 //)(maertsraelc di ov
{
;1- nruter
}
}
。境环发开的谐
统系作操 swodniW 于基个一是且而�器译编++C 个一是仅不 0.6++C lausiV
�中际实以所。0.4TN swodniW 和 PX swodniW,0002 swodniW 于用适只�性限局 的大很的用应的它但�)0.7++C lausiV(TEN.++C lausiV 了出推司公软微然虽
>melE ssalc< etalpmet
kcatS ssalc
;ldne<<e<<" : si mele"<<tuoc//
} {
;}
)l(knil,)e(mele:)LLUN=l* >melE<edoNkcatS ,0=e melE( edoNkcatS
数据结构与算法分析实验报告(川大)
数据结构与算法分析实验报告(川大)《数据结构与算法分析》课程设计报告课题名称:文本编辑器课题设计人(学号):刘佳玉2012141461134指导教师:朱宏评阅成绩:评阅意见:{case 'a'://当用户选择自行输入文本时······break;case 'b'://当用户选择使用电脑设置的文本时·····break;}2、当用户选择自己输入文本时,就需要写一些函数来存储这些信息,可以将这些函数封装在一个模板类中,只要定义一个之歌类的对象(bianji)就可以在需要的时候调用类的函数。
在这个时候需要调用的函数有:bianji.Sethang(h);//设置文本的行数bianji.Setlie(l);//设置文本的列数bianji.Setwenben();//输入文本bianji.Showwenben();//显示文本3、单用户选择使用程序初始化的文本时,只要显示文本即可。
这个时候需要的函数有:bianji.Showwenben();//显示文本4、该文本编辑器有插入,移除,替换,查找,显示和重置的功能,通过输出语句告知用户文本编辑器的功能,并询问用户要使用哪个功能。
相应代码:char ch='s';//初始化chwhile(ch!='q')//当ch!='q'时,就不会退出循环{cout<<"i代表插入文本 ";cout<<"R代表移除文本 ";cout<<"r代表替换文本 ";cout<<"f代表查找文本 ";cout<<"s代表显示当前文本 ";cout<<"n代表重新建立一个文本 ";cout<<"q代表退出 "<<endl;cout<<"请输入你的选择:";cin>>ch;······}5、当用户选择插入(insert)功能时,就只需要将当前行数加1,将要插入的行及其后面的行的文本往后移一行,在输入要插入的行的文本即可,相应代码:while(h0>bianji.Gethang()||h0<1)//如果要插入的行大于已有的//最大行或者小于第一行就会要求重新输入一个{cout<<"输入错误,请重输:";cin>>h0;}bianji.Sethang(bianji.Gethang()+1);//当前行数加1int i,j;for(i=bianji.Gethang()-1;i>=h0;i--)//把要插入行及后面的行的//文本往后一次移一行{for(j=0;j<bianji.Getlie();j++){bianji.Xiugaiwenben(i,j,i-1,j);}}for(i=0;i<bianji.Getlie();i++)//输入要插入的那一行的文本{cout<<"请输入第"<<h0<<"行第"<<i+1<<"个字符:";bianji.Fuzhiwenben(h0-1,i);cout<<endl;bianji.Showwenben();//显示文本6、当用户选择移除(remove)功能时,只需要将要移除的行的后面的文本依次往前移一行,就会顺便把要移除行的文本覆盖了,相当于达到了移除的效果,相应代码:while(h1>bianji.Gethang()||h1<1)//如果要移除的行大于已有的//最大行或者小于第一行就会要求重新输入一个{cout<<"输入有误,请重输:";cin>>h1;}bianji.Sethang(bianji.Gethang()-1);//将当前行数减1int i1,j1;for(i1=h1-1;i1<bianji.Gethang();i1++)//把要移除的行的后面的//行一次往前移一行就顺便把要移除的那一行给覆盖{ //了,从而达到移除的效果for(j1=0;j1<bianji.Getlie();j1++){bianji.Xiugaiwenben(i1,j1,i1+1,j1);}}bianji.Showwenben();7、当用户选择替换(replace)功能时,只需要重新输入要替换行的文本即可,其他行的文本不变,相应代码:for(i2=0;i2<bianji.Getlie();i2++) //得到要替换的那一行的列//数,然后输入新的文本{cout<<"请输入第"<<h2<<"行第"<<i2+1<<"个字符:";bianji.Fuzhiwenben(h2-1,i2);cout<<endl;bianji.Showwenben();8、当用户选择查找(find)功能时,只要用户输入相应列数的文本,然后将其与每一行的文本进行比较,如果完全相同,则会输出相应的行号,通过循环语句来进行匹配,相应代码:for(i3=0;i3<bianji.Getlie();i3++)//根据当前文本的列数来输入//要查找的文本{cout<<"请输入第"<<i3+1<<"列的字符:";bianji.Fuzhiwenben(bianji.Gethang(),i3);//将输入的文本放//到当前的最后一行,只是暂时的} //在这个功能完了后就会//消失,因为没有改变文本的行列for(i3=0;i3<bianji.Gethang();i3++)//根据输入的文本,一行一行//的搜,将每一行的文本域输入的文本进行匹配{ //如果匹配成功就会输出相应的行数j3=0;while(bianji.Findwenben(i3,j3)==bianji.Findwenben(bianji.Gethang(),j3)&&j3<bianji.Getlie()){j3++;//相同就会在查下一列的字符是否相同,直到这一完// 了}if(j3==bianji.Getlie()){cout<<"你要找的文本在第"<<i3+1<<"行"<<endl;count+=1;}}if(count==0)cout<<"你要找的文本不在现有文本中"<<endl;}cout<<endl;9、当用户选择显示(show)功能时,只需要调用模板类中的显示函数即可,相应代码:bianji.Showwenben();与初始化的部分相同,也只是要调用模板类中的相应函数即可,相应代码:cout<<"请输入新的行数:";cin>>h4;bianji.Sethang(h4);//新行cout<<"请输入新的列数:";cin>>l4;bianji.Setlie(l4);//新列bianji.Setwenben();//新文本bianji.Showwenben();//显示文本10、当用户选择重置(new)功能时,五、源程序清单:该程序代码分为3部分,分别是:1、模板类的代码,文件名“linklist.h”,相应代码:#ifndef LINKLIST_H_#define LINKLIST_H_#include<iostream>using namespace std;template<class ElemType>//队列的模板类class LinkList{private:ElemType wenben[256][256];//创立一个二维数组作为存储文本的空间int hang;//数组的行int lie;//数组的列public:LinkList()//构造函数{hang=1;//初始化行数为1lie=1;//初始化列数为1wenben[0][0]='a';//初始化文本为'a'}~LinkList(){}//析构函数void Xiugaiwenben(int h1,int l1,int h2,int l2)//修改文本,将文本中h2行l2列的{ //字符赋给h1行l1列wenben[h1][l1]=wenben[h2][l2];}void Fuzhiwenben(int h,int l)//给文本中h行l列赋一个字符{cin>>wenben[h][l];}ElemType Findwenben(int h,int l)//返回h行l列的字符{return wenben[h][l];}void Sethang(int h)//设定数组的行数{hang=h;}int Gethang()//得到数组的行数{return hang;}void Setlie(int l)//设定数组的列数{lie=l;}int Getlie()//得到数组的列数{return lie;}void Setwenben()//设立一个文本{int i,j;for(i=0;i<hang;i++){cout<<"请输入第"<<i+1<<"行的文本:"<<endl;for(j=0;j<lie;j++){cout<<"请输入第"<<i+1<<"行第"<<j+1<<"列的字符"<<endl;cin>>wenben[i][j];}}}void Showwenben()//显示当前文本{cout<<"当前文本是:"<<endl;int i,j;for(i=0;i<hang;i++){for(j=0;j<lie;j++){cout<<wenben[i][j];}cout<<endl;}}};#endif2、编辑类的代码,文件名是“editor.h”,相应代码:#include"linklist.h"class Editor{private:LinkList<char>bianji;//模板类的char型对象,用来调用模板类中的函数int count;//在使用查找功能时用来判断是否要查找的文本在当前文本中public:void Chushihua()//设置文本的函数{cout<<"a代表自己输入文本,b代表使用电脑设置的文本"<<endl;cout<<"请输入你的选择:"<<endl;char ch;cin>>ch;switch(ch)//对用户的不同选择执行不同的代码{case 'a'://当用户选择自行输入文本时cout<<"请输入文本的行数:";int h;cin>>h;cout<<endl;cout<<"请输入文本的列数:";int l;cin>>l;bianji.Sethang(h);//设置文本的行数bianji.Setlie(l);//设置文本的列数bianji.Setwenben();//输入文本bianji.Showwenben();//显示文本break;case 'b'://当用户选择使用电脑设置的文本时bianji.Showwenben();//显示初始化的文本break;}}void Edite()//编辑文本的函数{char ch='s';//初始化chwhile(ch!='q')//当ch!='q'时,就不会退出循环{cout<<"i代表插入文本";cout<<"R代表移除文本";cout<<"r代表替换文本";cout<<"f代表查找文本";cout<<"s代表显示当前文本";cout<<"n代表重新建立一个文本";cout<<"q代表退出"<<endl;cout<<"请输入你的选择:";cin>>ch;switch(ch)//根据用户的不同选择执行不同的代码{case 'i'://选择插入(insert)功能bianji.Showwenben();//显示当前文本cout<<"请问要插入到第几行?:";int h0;cin>>h0;while(h0>bianji.Gethang()||h0<1)//如果要插入的行大于已有的最大行或者小于第一行就会要求重新输入一个{cout<<"输入错误,请重输:";cin>>h0;}bianji.Sethang(bianji.Gethang()+1);//当前行数加1int i,j;for(i=bianji.Gethang()-1;i>=h0;i--)//把要插入行及后面的行的文本往后一次移一行{for(j=0;j<bianji.Getlie();j++){bianji.Xiugaiwenben(i,j,i-1,j);}}for(i=0;i<bianji.Getlie();i++)//输入要插入的那一行的文本{cout<<"请输入第"<<h0<<"行第"<<i+1<<"个字符:";bianji.Fuzhiwenben(h0-1,i);cout<<endl;}bianji.Showwenben();//显示文本break;case 'R'://选择移除(remove)功能bianji.Showwenben();cout<<"请问要移除哪一行?:";int h1;cin>>h1;while(h1>bianji.Gethang()||h1<1)//如果要移除的行大于已有的最大行或者小于第一行就会要求重新输入一个{cout<<"输入有误,请重输:";cin>>h1;}bianji.Sethang(bianji.Gethang()-1);//将当前行数减1int i1,j1;for(i1=h1-1;i1<bianji.Gethang();i1++)//把要移除的行的后面的行一次往前移一行就顺便把要移除的那一行给覆盖{ //了,从而达到移除的效果for(j1=0;j1<bianji.Getlie();j1++){bianji.Xiugaiwenben(i1,j1,i1+1,j1);}}bianji.Showwenben();break;case 'r'://选择替换(replace)功能bianji.Showwenben();cout<<"要替换哪一行?:";int h2;cin>>h2;int i2;for(i2=0;i2<bianji.Getlie();i2++)//得到要替换的那一行的列数,然后输入新的文本{cout<<"请输入第"<<h2<<"行第"<<i2+1<<"个字符:";bianji.Fuzhiwenben(h2-1,i2);cout<<endl;}bianji.Showwenben();break;case 'f'://选择查找(find)功能bianji.Showwenben();cout<<"请输入要查找的文件:"<<endl;int i3,j3;count=0;for(i3=0;i3<bianji.Getlie();i3++)//根据当前文本的列数来输入要查找的文本{cout<<"请输入第"<<i3+1<<"列的字符:";bianji.Fuzhiwenben(bianji.Gethang(),i3);//将输入的文本放到当前的最后一行,只是暂时的} //在这个功能完了后就会消失,因为没有改变文本的行列/*cout<<"第"<<h3<<"行的文本是:"<<endl;//输入行数就会将当前文本中那一行的文本输出for(i3=0;i3<bianji.Getlie();i3++){cout<<bianji.Findwenben(h3-1,i3);}*/for(i3=0;i3<bianji.Gethang();i3++)//根据输入的文本,一行一行的搜,将每一行的文本域输入的文本进行匹配{ //如果匹配成功就会输出相应的行数j3=0;while(bianji.Findwenben(i3,j3)==bianji.Findwenben(bianji.Getha ng(),j3)&&j3<bianji.Getlie()){j3++;//相同就会在查下一列的字符是否相同,直到这一行完了}if(j3==bianji.Getlie()){cout<<"你要找的文本在第"<<i3+1<<"行"<<endl;count+=1;}}if(count==0){cout<<"你要找的文本不在现有文本中"<<endl;}cout<<endl;break;case 's'://选择显示当前文本bianji.Showwenben();break;case 'n'://选择重置(new)功能int h4,l4;cout<<"请输入新的行数:";cin>>h4;bianji.Sethang(h4);//新行cout<<"请输入新的列数:";cin>>l4;bianji.Setlie(l4);//新列bianji.Setwenben();//新文本bianji.Showwenben();//显示文本break;case 'q':break;}}}};3、主函数的代码,文件名是“main.cpp”,相应代码:#include"linklist.h"#include"editor.h"int main(){Editor e;//编辑类的对象,用来调用类中的函数e.Chushihua();//调用设置文本的函数e.Edite();//调用编辑文本的函数return 0;}六、运行结果:1、选择自己输入文本(a),输入文本为(3行2列):qwerty进行插入操作(i),插入文本as到第2行:进行移除操作(R),移除第3行文本:进行替换操作(t),将第一行文本qw替换为df:进行查找操作(f),查找文本as和qw:进行显示操作(s):进行重置操作(n):重置操作和自己输入文本是一样的,在这里就不演示了,有兴趣可以自己尝试。
《数据结构课程设计》表达式求值实验报告
实验课程名称专业班级学生姓名学号指导教师20 至 20 学年第学期第至周算术表达式求值演示一、概述数据结构课程设计.要求学生在数据结构的逻辑特性和物理表示、数据结构的选择和应用、算法的设计及其实现等方面.加深对课程基本内容的理解。
同时.在程序设计方法以及上机操作等基本技能和科学作风方面受到比较系统和严格的训练。
在这次的课程设计中我选择的题目是算术表达式求值演示。
表达式计算是实现程序设计语言的基本问题之一.也是栈的应用的一个典型例子。
设计一个程序.演示用算符优先法对算术表达式求值的过程。
深入了解栈和队列的特性.以便在解决实际问题中灵活运用它们.同时加深对这种结构的理解和认识。
二、系统分析1.以字符列的形式从终端输入语法正确的、不含变量的整数表达式。
利用已知的算符优先关系.实现对算术四则混合运算表达式的求值.并仿照教科书的例子在求值中运算符栈、运算数栈、输入字符和主要操作的变化过程。
2.一般来说.计算机解决一个具体问题时.需要经过几个步骤:首先要从具体问题抽象出一个适当的数学模型.然后设计一个解决此数学模型的算法.最后编出程序.进行测试.调试直至得到想要的答案。
对于算术表达式这个程序.主要利用栈.把运算的先后步骤进行分析并实现简单的运算!为实现算符优先算法.可以使用两个栈.一个用以寄存运算符.另一个用以寄存操作数和运算结果。
3.演示程序是以用户于计算机的对话方式执行.这需要一个模块来完成使用者与计算机语言的转化。
4.程序执行时的命令:本程序为了使用具体.采用菜单式的方式来完成程序的演示.几乎不用输入什么特殊的命令.只需按提示输入表达式即可。
(要注意输入时格式.否者可能会引起一些错误)5. 测试数据。
三、概要设计一个算术表达式中除了括号、界限符外.还包括运算数据和运算符。
由于运算符有优先级别之差.所以一个表达式的运算不可能总是从左至右的循序执行。
每次操作的数据或运算符都是最近输入的.这与栈的特性相吻合.故本课程设计借助栈来实现按运算符的优先级完成表达式的求值计算。
数据结构课程实践报告模板-表达式计算
表达式计算1、问题描述与分析算数表达式一般都写成中缀形式,即运算符总是出现在两个操作数之间(单目运算符除外),称为中缀表达式。
编译系统对中缀表达式的处理方法是先把它转换为后缀表达式。
在后缀表达式中,运算符位于两个操作数的后面,并且没有括号,其运算符次序就是其执行计算的次序。
后缀表达式计算过程的规则非常简单:从左到右依次扫描,当读到运算符时,就对该运算符前面的两个操作数执行相应的运算,直至得到表达式的结果。
本程序主要模拟编译系统计算中缀表达式的过程,先将中缀表达式转换成相应的后缀表达式,再根据后缀表达式计算出表达式的值。
这个问题的解决主要是栈的一个应用。
因为本程序仅是模拟,没有判断输入的中缀表达式是否合法,容错性不强,另外也仅能对一位数的中缀表达式进行转换和计算,功能上还有许多局限性,本程序处理的中缀表达式中仅允许出现六种运算符,且都是双目运算符。
2、数据结构设计和基本算法设计方法的选择2.1 中缀表达式转换成后缀表达式为完成中缀表达式转换成相应的后缀表达式,设计了infix2postfix类。
为了方便用户使用,它只有4个接口函数,包括两个构造函数,一个设置中缀表达式的函数setInfixExp 和一个返回后缀表达式的函数postfixExp。
所有表达式均采用string来存储,运算符用堆栈来临时存储,并用map的数据结构来定义优先级。
下面给出了infix2posfix类的声明和部分定义。
class infix2postfix{public:infix2postfix(){};infix2postfix(const string& infixExp):infix(infixExp){};void setInfixExp(const string& infixExp){infix=infixExp;};string postfixExp();private:string infix; //用于转换的中缀表达式string postfix; //后缀表达式stack<string> stk;//用于存储运算符的堆栈map<string,int> oper_prio;//用于存储运算符的优先级void set_priority();//设置运算符('+','-','*','/','%','^')的优先级};中缀表达式转换成后缀表达式功能的实现是栈的一个典型应用,主要应用栈的“后进先出”的特性及预先设计好的运算符优先级。
数据结构课程设计带括号的算术表达式求值
、实验的目的和要求1.采用算符优先数算法, 能正确求值表达式;2.熟练掌握栈的应用;3•熟练掌握计算机系统的基本操作方法,了解如何编辑、编译、链接和运行一个C++程序; 4.上机调试程序,掌握查错、排错使程序能正确运行。
三、实验的环境:指硬件和软件环境1.硬件环境: Intel 奔腾双核T2390 双核处理器(1.86GHz 主频/1MB 二级缓存/533MHz 前端总线), RAM:2G .2.软件环境: 操作系统:windows vista编译软件:Microsoft Viual C++6.03.软件环境介绍:Visual C++是一个功能强大的可视化软件开发工具。
自1993年Microsoft公司推出Visual C++1.0后,随着其新版本的不断问世,Visual C++已成为专业程序员进行软件开发的首选工具。
虽然微软公司推出了Visual C++.NET(Visual C++7.0) ,但它的应用的很大的局限性,只适用于Windows 2000,Windows XP 和Windows NT4.0。
所以实际中,更多的是以Visual C++6.0 为平台。
Visual C++6.0不仅是一个C++编译器,而且是一个基于Windows操作系统的可视化集成开发环境( integrated development environment,IDE )。
Visual C++6.0 由许多组件组成,包括编辑器、调试器以及程序向导AppWizard 、类向导Class Wizard 等开发工具。
这些组件通过一个名为Developer Studio 的组件集成为和谐的开发环境。
四、算法描述:1.头文件:Stack.hCalculator.hMethod:Stack method:Push(); // 进栈操作Pop(); // 出栈操作GetHead(); // 返回栈中的最顶层元素MakeEmpty(); // 清空栈操作Calculator method:Calculator();// 计算主体celarstream(); // 清空输入流Prior();// 返回运算符的优先级done(); // 做一次二元运算output(); // 打印结果并输出EnEmpty(); // 调用MakeEmpty(), 并清空栈2.cpp 文件Calculator.cppMethod:int main(); // 主程序3.程序流程图优先级比较算法Data 算法存放操作字符 存放数据调用 Calculator 。
《带括号的表达式求值》课程设计报告
《数据结构与算法分析》课程设计报告课题名称:带括号的算术表达式求值课题负责人名(学号): **********同组成员名单(角色):戴维指导教师:评阅成绩:评阅意见:提交报告时间:200 年月日课程名称:数据结构学生姓名:戴维学生学号:0743111298带括号的算术表达式求值软件工程专业学生戴维指导老师朱宏一、实验一:带括号的算术表达式求值二、实验的目的和要求:1.采用算符优先数算法,能正确求值表达式;2.熟练掌握栈的应用;3.熟练掌握计算机系统的基本操作方法,了解如何编辑、编译、链接和运行一个C++程序;4.上机调试程序,掌握查错、排错使程序能正确运行。
三、实验的环境:1.硬件环境:Intel(R) Celeron(R)M CPU***********1.60GHz , 0.99Gb内存2.软件环环境:操作系统:Microsoft Windows XPProfessinal 版本2002编译系统版本:MicroSoft Visual C++6.0包括操作系统,编译系统的版本的特点,编辑软件特点等。
四、算法描述:对于带有括号的算术表达式有以下的运算法则:1.先乘方,再乘除,最后加减。
2.同级运算从左到右。
3.先括号内,再括号外。
具体实现如下:1.先建立两个堆栈,一个是操作符堆栈,一个为操作数堆栈。
并且将这两个堆栈先清空,然后在操作符号堆栈当中放入一个“=”,以便在后面方便判断表达式是否结束。
2.从输入流当中读取一个字符,循环执行下面的操作:⑴去出操作符号堆栈的栈顶元素,如果栈顶元素是不是“=”并且如果当前的字符也是“=”的时候,那么表示表达式已经结束了,当前操作数堆栈的栈顶元素就是表达式的值。
⑵如果当前字符不是操作符,就将当前字符放回到输入流当中,读取操作数,并且将操作数加入到操作数堆栈当中,继续读入下一个字符。
⑶如果当前字符是操作符就进行下面的操作:①.如果当前字符不是“+”或者“-”,则在当前字符前面加一个“0”放入到操作数栈当中。
《数据结构》课程设计_排序算法比较以及算术表达式求值
XXXXX大学《数据结构》课程设计报告排序算法比较算术表达式求值班级:学号:姓名:指导老师:目录一课程设计1——排序算法比较一、需求分析二、程序的主要功能三、程序运行平台四、数据结构五、算法及时间复杂度六、测试用例七、程序源代码二课程设计2——算术表达式求值一、需求分析二、程序的主要功能三、程序运行平台四、数据结构五、算法及时间复杂度六、测试用例七、程序源代码三感想体会与总结排序算法比较一、需求分析利用随机函数产生N个随机整数(N = 500,1000,1500,2000,2500,…,30000),利用直接插入排序、折半插入排序,起泡排序、快速排序、选择排序、堆排序,基数排序七种排序方法(可添加其它排序方法)进行排序(结果为由小到大的顺序),并统计每一种排序所耗费的时间(统计为图表坐标形式)。
二、程序的主要功能1.用户输入任意个数,产生相应的随机数2.用户可以自己选择排序方式(直接插入排序、折半插入排序、起泡排序、快速排序、选择排序、堆排序、基数排序)的一种3.程序给出原始数据、排序后从小到大的数据,并给出排序所用的时间。
三、程序运行平台Visual C++ 6.0版本四、数据结构本程序的数据结构为线形表,线性顺序表、线性链表。
1、结构体:typedef struct{int *r; //r指向线形表的第一个结点。
r[0]闲置,不同的算法有不同的用处,如用作哨兵等。
int length; //顺序表的总长度}Sqlist;2、空线性表Status InitSqlist(Sqlist &L){L.r=(int *)malloc(MAXSIZE*sizeof(int)); //分配存储空间if(!L.r){printf("存储分配失败!");exit(0);} //存储分配失败L.length=0;//初始长度为0return OK;}五、算法及时间复杂度(一)各个排序是算法思想:(1)直接插入排序:将一个记录插入到已排好的有序表中,从而得到一个新的,记录数增加1的有序表。
《数据结构和算法设计》实验报告
《数据结构与算法设计》实验报告——实验二一、实验目的按照四则运算加、减、乘、除、幂(^)和括号的优先关系和惯例,编写计算器程序。
二、实验内容简单计算器。
请按照四则运算加、减、乘、除、幂(^)和括号的优先关系和惯例,编写计算器程序。
要求:①从键盘输入一个完整的表达式,以回车作为表达式输入结束的标志。
②输入表达式中的数值均为大于等于零的整数。
中间的计算过程如果出现小数也只取整。
例如,输入:4+2*5= 输出:14输入:(4+2)*(2-10)= 输出:-48三、程序设计概要设计1、宏定义#define TRUE 1#define FALSE 0#define OK 1#define ERROR 02、基本函数:(1)void InitStack_char(SqStack *S) //char型栈初始化(2)void InitStack_int(sqStack *S) //int型栈初始化(3)void Push_char(SqStack *S,char ch) //char型元素进栈(4)void Push_int(sqStack *S,int num) //int型元素进栈(5)char GetTop_char(SqStack *S) //取char型栈顶元素(6)int GetTop_int(sqStack *S) //取int型栈顶元素(7)Status In(char c) //判断是否为运算符,若是运算符则返回,否则返回(8)char Precede(char a,char b) //判断两运算符的先后次序(9)Status Pop_char(SqStack *S,char &x) //char型栈出栈(10)Status Pop_int(sqStack *S,int &x) //int型栈出栈(11)int Operate(int a,char theta,int b) //计算a和b运算结果3、流程图详细设计数据类型typedef struct node //构造char型栈{char ch;struct node *next;}node;typedef struct{struct node *base;struct node *top;}SqStack;typedef struct lnode //构造int型栈{int num;struct lnode *next;}lnode;typedef struct{struct lnode *base;struct lnode *top;}sqStack;操作部分void InitStack_char(SqStack *S){S->base = (node *)malloc(sizeof(node));S->base->next=NULL;S->top = S->base;} //char型栈初始化void InitStack_int(sqStack *S){S->base = (lnode *)malloc(sizeof(lnode));S->base->next=NULL;S->top = S->base;} //int型栈初始化void Push_char(SqStack *S,char ch){node *p;p=(node*)malloc(sizeof(node));p->ch=ch;p->next=S->top;S->top=p;} //char型元素进栈Status Push_int(sqStack *S,int num){lnode *p;p=(lnode*)malloc(sizeof(lnode));p->num=num;p->next=S->top;S->top=p;return OK;} //int型元素进栈char GetTop_char(SqStack *S){return (S->top->ch);} //取char型栈顶元素int GetTop_int(sqStack *S){return (S->top->num);} //取int型栈顶元素Status Pop_char(SqStack *S,char &x){if(S->base == S->top)return ERROR;node *p;p=S->top;x=p->ch;S->top=p->next;free(p);return OK;} //char型栈出栈Status Pop_int(sqStack *S,int &x){if(S->base == S->top)return ERROR;lnode *p;p=S->top;x=p->num;S->top=p->next;free(p);return OK;} //int型栈出栈计算功能int Operate(int a,char theta,int b){int i,z = 1;switch(theta){case '+':z = (a + b);break;case '-':z = (a - b);break;case '*':z = (a * b);break;case '/':z = (a / b);break;case '^':for(i = 1;i<=b;i++)z = z*a;break;}return (z);} //计算a和b运算结果Status In(char c){if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='='||c=='^') return OK;elsereturn ERROR;} //判断是否为运算符char Precede(char a,char b){if(a=='+'||a=='-'){if(b=='+'||b=='-'||b==')'||b=='=')return '>';elsereturn '<';}if(a=='*'||a=='/'){if(b=='('||b=='^')return '<';elsereturn '>';}if(a=='('){if(b==')')return '=';elsereturn '<';}if(a==')'){if(b!='(')return '>';}if(a=='#'){if(b=='=')return '=';elsereturn '<';}if(a=='^')return ('>');} //判断两运算符的先后次序主函数int main() //主函数{char c,x,theta;int a,b,c1; //定义变量SqStack OPTR; //定义字符栈sqStack OPNR; //定义整型栈InitStack_char(&OPTR); //初始化InitStack_int(&OPNR); //初始化Push_char(&OPTR,'#'); //将字符型栈底设为#c = getchar(); //从键盘输入得到字符while(c!='='||GetTop_char(&OPTR)!='#') //判定是否执行循环if(!In(c)){c1 = 0;while(!In(c)){c1 = c1*10+c-'0';c = getchar();}Push_int(&OPNR,c1);} //当扫描字符不是运算符时,转化为整型数存入栈中else{switch(Precede(GetTop_char(&OPTR),c)) //判定运算符的优先关系{case '<':Push_char(&OPTR,c);c = getchar();break; //当前运算符优先级高,存入char栈case '=':Pop_char(&OPTR,c);c = getchar();break; //运算符次序相等,存入char栈case '>': //当前运算符优先级低Pop_char(&OPTR,theta);Pop_int(&OPNR,b);Pop_int(&OPNR,a);Push_int(&OPNR, Operate(a,theta,b));//计算运算结果,并存入int栈break; //继续循环}}printf("%d\n",GetTop_int(&OPNR)); //计算完成,取出int栈顶元素,并输出return 0;}四、程序调试分析编写程序的过程中遇到了很多的问题,最突出的两个问题就是整数和两位数的运算处理,一开始修改了主函数部分之后,原来可以执行一位数运算的程序出现了error,由于没有及时保存,并且之前的代码无法恢复,只得重新编写一次。
【2012四川大学,数据结构与算法设计】数据结构与算法分析教学大纲(计)
《数据结构与算法分析》大纲一、目的与任务《数据结构与算法分析》是计算机科学与技术专业的核心基础课程之一。
数据是计算机处理的对象,本门课程研究的数据是非数值性、结构性的数据。
学习本门课程要求掌握各种主要数据结构的特点,计算机内的表示方法,处理数据的算法设计,对于算法所花费的时间和空间代价的分析也要求有一定程度的了解和掌握,以及在计算机科学中最基本的应用。
通过本门课程的学习,要求学生能够组织,处理数据的理论和方法,培养训练学生选用合适的数据结构,能编写质量高,风格好的应用程序及初步评价算法程序的能力。
《数据结构与算法分析》的先行课程是计算机导论,C语言、C++语言、离散数学及概率等;后继课程有操作系统、编译原理、数据库原理、人工智能等。
学生学习时应注意本门课的特点:首先搞清楚各种数据结构的定义(逻辑结构),然后研究其可能的存储结构(物理结构),最后是一定存储结构上算法的实现。
另外,配合适量的习题,辅以一定学时数的上机实践也是非常必要的,使学生在系统软件、应用软件特别是非数值软件的开发打下良好的理论基础的实践基础。
二、课程内容1.绪论(3学时)数据、数据元素、数据对象、数据类型、数据结构;算法、算法与数据结构的关系;描述算法的方法;时间复杂度、空间复杂度及编写算法的人工复杂度等、重点是时间复杂度即基本算法分析方法。
2.线性表(6学时)(1)线性表的(逻辑)定义与基本运算。
(2)线性表的顺序存储结构及基本运算的实现。
(3)线性表的链式存储结构(单链表、循环链表、双向链表)及其基本运算。
(4)一元多项式的表示及相加。
3.栈和队(5学时)(1)栈的定义及运算、栈的顺序存储及链接存储,栈的应用——算术表达式的求值,多栈共享存储空间。
(2)队列的定义及运算,队列的顺序存储与循环队列,队列的链接存储,双端队列4.串(3学时)串的概念及基本运算,串的存储结构,串的应用举例——文本编辑。
5.数组和广义表(3学时)数组的定义、运算、存储结构、特殊矩阵及稀疏矩阵的压缩存储;广义表的定义、存储结构与应用。
《带括号算术表达式的计算》实验报告
四川大学数据结构与算法分析实验报告实验名称:带括号的算术表达式求值指导老师:________孙界平________学院:_______软件学院_______专业:_______软件工程_______姓名:________马健________学号:_____2013141463026____班级:________5 班________日期:___2014年10月24日___目录一实验题目 (3)二实验目的和要求 (3)三实验环境 (3)四算法描述 (3)五源程序清单........................................................ 附录六运行结果. (6)七实验运行情况分析 (7)一、实验题目:●带括号的算术表达式求值二、实验目的和要求:✓采用算符优先数算法,能正确求值表达式;✓熟练掌握栈的应用;✓熟练掌握计算机系统的基本操作方法,了解如何编辑、编译、链接和运行一个C程序;✓上机调试程序,掌握查错、排错使程序能正确运行。
三、实验的环境:✧硬件环境:联想笔记本电脑✧软件环境:操作系统: windows 7 旗舰版编译软件:Visual C++ 6.0四、算法描述:➢➢文字解释:1.用户从键盘读入算术中缀表达式,以”=”结尾;2.程序判断用户输入表达式是否正确;3.若表达式正确,则用栈计算算术表达式;4.打印输出计算过程和最终结果;5.程序询问用户是否继续计算;6.若继续,则执行第1步;若否定,则退出程序7.若表达式错误,则打印错误信息,提示用户重新输入8.返回第1步;➢函数及结构说明:●结构体:1) 存储算数表达式的单链表:struct Expression{char sign;struct Expression *next;};2) 操作符和操作数栈:typedef struct{char *top;char *bottom;int stack_size;}Stack;●构造函数:1) 栈相关操作函数:①初始化空栈int StackCreate(Stack *s);②入栈操作int PUSH(Stack *s, char c);③出栈操作int POP(Stack *s, char c);④获取栈顶元素char GetTop(Stack *s);2) 计算相关操作函数:①利用栈计算算术表达式int Calculate(struct Expression *exp);②子式的值的计算int Count(char num1, char sign, char num2);③判断字符是否为运算符int IsOpOrNum(char c);④判断运算符优先级char JudgeLevel(char c1, char c2);⑤判断表达式正确性int IsExpresiion(struct Expression *exp);⑥输出计算结果void PrintResult(struct Expression *exp,int result);3) 算术表达式输入函数:①键盘读入存于单链表struct Expression *GetExp();●构造操作符优先级表五、源程序清单➢见附录六、运行结果➢测试表●本次测试采用用户从键盘输入算数表达式,共进行16组测试➢部分运行截图●基本计算操作●式子正误判断●容错能力●全体测试七、实验运行情况分析➢优点:●用户输入格式较为自由。
数据结构课程设计算术表达式求值
计算机科学系《数据结构课程设计》报告课题名称:算术表达式求值目录1.问题描述-----------------------------------------------------------32.基本要求-----------------------------------------------------------33.工具/准备工作----------------------------------------------------34.分析与实现--------------------------------------------------------45. 课程设计体会与感悟------------------------------------------161.问题描述从键盘上输入中缀算术表达式,包括括号,计算出表达式的值。
2.基本要求(1)程序能对所输入的表达式做简单的判断,如表达式有错,能给适当提示。
(2)能处理单目运算符:+,-。
3.工具/准备工作在开始项目之前,应回顾复习相关内容。
需要一台计算机装有visual C++。
4.分析与实现对于中缀表达式,一般运算规则如下:(1)先乘方,再乘除,最后加减;(2)同级运算从左算到右;(3)先括号内再括号外;(4)用到的头文件”utility.h”,”lk_stack.h”,”node.h”,”calculator.h”.根据实践经验,可以对运算符设置统一的优先级,从而方便比较。
表中给出了包括加、上面讨论的的+、—为双目运算符,如为单目运算符,编程实现时,可在前面加上0而转化为双目运算符。
如在+、—的前一个字符(如当前字符不是运算符时,规定用0表示)为‘=’或‘(’,则为单目运算符。
具体实现算法时,可设置两个工作栈,一个为操作栈,一个为操作符栈optr,另外一个为操作数栈opnd,算法基本思路如下:(1)将optr栈和opnd栈清空,在optr栈中加入一个‘=‘。
数据结构与算法课程设计报告
数据结构与算法分析课程设计报告课题名称: 1. txt编译器2. 带括号的算术表达式求值3. Huffman编码(二叉树用)4. 课表拓扑排序提交文档学生姓名:提交文档学生学号:同组成员名单:指导教师姓名:指导教师评阅成绩:指导教师评阅意见:..提交报告时间:2013年 1月 6日实验一:1.实验的目的和要求:<1>采用C++的ASCII码文件和串函数实现;<2>熟练掌握串运算的应用;<3>熟练掌握计算机系统的基本操作方法,了解如何编辑、编译、链接和运行一个C++程序;<4>上机调试程序,掌握查错、排错使程序能正确运行。
2.实验的环境:●硬件环境: Windows XP操作系统●软件环环境:Microsoft Visual Studio C++6.03.算法描述:●类的层次结构EditorNext_line();goto_line();insert_line();substitute_line();change_line();read_file();write_line();find_string();●测试程序说明按行读取文件->显示文本内容->删除指定行->在指定行插入->显示指定行内容4.源程序清单:(程序文字:6号字体,行距12磅)#include <iostream>#include <string>#include <fstream>#include <cmath>#include <cstdlib>using namespace std;/*链表的节点。
保存文件中一行的内容*/struct Line{int id;string content;struct Line* next;};class TextEditor{public:// 文件中一行最多的字符数enum{MAX_SIZE_PER_LINE = 10000};/*构造函数参数:fileName 文件路径*/TextEditor(string fileName);/*打印文件内容*/void print();/*保存文件*/void save();/*为文件增加一行参数:lineIndex 要增加的行所在行号content 要增加的行的内容返回:添加成功返回 true ,否则返回 false*/bool addLine(int lineIndex,string content);/*为文件删除一行参数:lineIndex 要删除的行所在行号返回:删除成功返回 true ,否则返回 false*/bool deleteLine(int lineIndex);/*为文件修改一行参数:lineIndex 要修改的行所在行号content 要修改的行的修改后的内容返回:修改成功返回 true ,否则返回 false*/bool modifyLine(int lineIndex,string content);/*搜索文件中的行参数:keyword 要搜索的行含有的关键字返回:搜索结果,是一个链表*/struct Line * searchLines(string keyword);/*查询文件的总行数返回:文件的总行数*/int getNumOfLines();private:// 文件路径string fileName;// 链表形式,按行存储文件在内存中struct Line * artical;};TextEditor::TextEditor(string fileName){this->fileName = fileName;this->artical = NULL;ifstream fin(this->fileName.c_str());if(fin){int lineId = 0;struct Line * pr, *p;char *buffe = new char[MAX_SIZE_PER_LINE+1];while(!fin.eof()){p = new struct Line();// 生成行号p -> id = ++ lineId;// 文件读入行内容fin.getline(buffe,MAX_SIZE_PER_LINE);p -> content = string(buffe);// 初始化指针p -> next = NULL;// 添加新的一行(新的节点)if(this->artical == NULL){this->artical = p;pr = p;}else{pr -> next = p;pr = p;}}}fin.close();}void TextEditor::print(){struct Line *p = this->artical;// 输出的行号的宽度int lineIdWidth = (int)log10(this->getNumOfLines()) + 1;while(p){// 设置行号输出的宽度cout.width(lineIdWidth);cout << (p -> id) << " : " << (p -> content) << endl;p = p -> next;}}void TextEditor::save(){ofstream fout(this->fileName.c_str());if(fout){struct Line *p = this->artical;while(p){fout << p->content;// 不是最后一行,输出一个换行符号if(p -> next != NULL){fout << endl;}p = p->next;}}fout.close();}bool TextEditor::addLine(int lineIndex,string content){int numOfLines = this->getNumOfLines();// 要插入新行的位置不合法if(lineIndex < 1 || lineIndex > (numOfLines+1)){return false;}else{// 新行struct Line * newLine = new struct Line();// 生成行号newLine -> id = lineIndex;// 行内容newLine -> content = content;// 初始化指针newLine -> next = NULL;if(this->artical == NULL){this->artical = newLine;}else{struct Line * pr = this->artical , *p = pr ;// 找到要插入行的位置while(p && (lineIndex > p->id )){pr = p;p = p -> next;}// 插入第一行特别处理if(lineIndex == 1){p = newLine -> next = this -> artical;this -> artical = newLine;}else{p = newLine -> next = pr -> next;pr -> next = newLine;}// 更改插入行之后所有行的行号while(p){p -> id ++;p = p -> next;}}return true;}}bool TextEditor::deleteLine(int lineIndex){int numOfLines = this->getNumOfLines();// 要删除行的位置不合法if(lineIndex < 1 || lineIndex > numOfLines){return false;}else{struct Line * pr = this->artical , *p = pr ;// 找到要删除行的位置while(p && (lineIndex != p->id )){pr = p;p = p -> next;}// 删除第一行要特别处理if(lineIndex == 1){this -> artical = p -> next;free(p);p = this -> artical;}else{pr -> next = p -> next ;free(p);p = pr -> next;}// 更改删除行之后所有行的行号while(p){p -> id --;p = p -> next;}return true;}}bool TextEditor::modifyLine(int lineIndex,string content){int numOfLines = this->getNumOfLines();// 要修改行的位置不合法if(lineIndex < 1 || lineIndex > numOfLines){return false;}else{struct Line * pr = this->artical , *p = pr ;// 找到要修改行的位置while(p && (lineIndex != p->id )){pr = p;p = p -> next;}// 修改行的内容p -> content = content ;return true;}}struct Line * TextEditor::searchLines(string keyword){struct Line * p = this->artical ,*pr ,*searchResult = NULL ;while(p){// 当前行含有要搜索的关键字if(p -> content.find(keyword) != string::npos){// 生成一个匹配项struct Line * matchLine = new struct Line();matchLine -> id = p -> id;matchLine -> content = p -> content;matchLine -> next = NULL;// 添加到第一条搜素结果要特殊处理if(searchResult == NULL){searchResult = matchLine;pr = matchLine;}else{pr -> next = matchLine;pr = matchLine;}}p = p -> next;}return searchResult;}int TextEditor::getNumOfLines(){int numOfLines = 0;struct Line *p = this->artical;while(p){numOfLines++;p = p->next;}return numOfLines;}int main(int argc, char *argv[]){// 菜单while(1){/*第一级菜单*/cout<<"[B/b] B E G I N"<<endl;cout<<"[Q/q] Q U I T "<<endl;char ch_1;cin >> ch_1;switch(ch_1){case 'B':case 'b':{system("cls");cout<<"Welcom To My Editor"<<endl;cout << "Please input the file name:";string fileName;cin >> fileName;TextEditor textEditor(fileName);system("cls");// 输出文件内容//textEditor.print();while('B'||'b'){/*第二级菜单*/cout << endl;cout<<"---------[A/a] Add ------"<<endl;cout<<"---------[D/d] Del ------"<<endl;cout<<"---------[M/m] Modify ------"<<endl;cout<<"---------[S/s] Search ------"<<endl;cout<<"---------[R/r] Read ------"<<endl;cout<<"---------[H/h] Help ------"<<endl;cout<<"---------[B/b] Back ------"<<endl;char ch_2;cin >> ch_2;switch(ch_2){// 添加行case 'A':case 'a':{system("cls");cout << "Please input the linenum:[1~" << (textEditor.getNumOfLines()+1) << "] :";int lineIndex;cin >> lineIndex;cout << "Please input the content:" ;string content;cin >> content;if(textEditor.addLine(lineIndex,content)){cout << "Done!"<<endl;}else{cout << "Fall!"<<endl;}break;}// 删除行case 'D':case 'd':{system("cls");cout << "Please input the linenum[1~" << textEditor.getNumOfLines() << "] :";int lineIndex;cin >> lineIndex;if(lineIndex > textEditor.getNumOfLines()){cout<<"Errors: invalid linenum!"<<endl;}else{if(textEditor.deleteLine(lineIndex)){cout << "Done!"<<endl;}else{cout << "Fall!"<<endl;}}break;}// 修改行case 'M':case 'm':{system("cls");cout << "Please input the linenum[1~" << textEditor.getNumOfLines() << "] :";int lineIndex;cin >> lineIndex;if(lineIndex > textEditor.getNumOfLines()){cout<<"Errors: invalid linenum!"<<endl;}else{cout << "Please input the content:" ;string content;cin >> content;if(textEditor.modifyLine(lineIndex,content)){cout << "Done!"<<endl;}else{cout << "Fall!"<<endl;}}break;}// 搜索行case 's':case 'S':{system("cls");cout << "Please input the keyword:";string keyword;cin >> keyword;// 搜索行struct Line * searchResult = textEditor.searchLines(keyword) ,*p = searchResult;// 输出搜索结果cout << "search result:"<< endl;while(p){cout << p->id << " : " << endl << p->content << endl;p = p -> next;}break;}// 打印文件case 'R':case 'r':{system("cls");textEditor.print();break;}// 返回case 'H':case 'h':{system("cls");cout<<"Add : To add a line "<<endl;cout<<"Del : To delete a line"<<endl;cout<<"Modify : To modify a line"<<endl;cout<<"Search : To output a line which has the keyword"<<endl;cout<<"Read : San the file"<<endl;cout<<"Back : Back to the top"<<endl;break;}case 'B':case 'b':{system("cls");textEditor.save();break;}// 选择错误default:{system("cls");cout<<"Errors: invalid command"<<endl;break;}} // end switch// 从二级菜单返回一级菜单if(ch_2 == 'B'||ch_2 == 'b'){break;}}// end while(1)break;}case 'Q':case 'q':{exit(0);break;}default:{cout<<"Errors: invalid command"<<endl;break;}}}return 0;}5.运行结果:6.实验运行情况分析(包括算法、运行结果、运行环境等问题的总体讨论)。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
四川大学《数据结构与算法分析》课程设计报告-带括号的算术表达式《数据结构与算法分析》课程设计报告课题名称:带括号的算数表达式求值课题设计人(学号):指导教师:朱宏评阅成绩:评阅意见:提交报告时间:2014 年12月9日带括号的算数表达式求值计算机类专业学生指导老师朱宏[摘要] 在平时的生活中,我们可以解决一些简单的算术表达式,如果当我们遇到一些式子较为冗长,运算比较复杂的算术表达式时,我们都会选择计算器。
那么,计算器又是通过怎样的原理来进行运算的呢。
本程序利用堆栈先进后出的特点,采用操作数和操作符两个堆栈,实现由中缀表达式到后缀表达式的转换并求值的过程。
带括号的算术表达式的求值是堆栈的一个典型的应用实例。
关键词:计算器堆栈C++-1-一、实验名称:带括号的算术表达式求值二、实验的目的和要求:1.采用算符优先数算法,能正确求值表达式;2.熟练掌握栈的应用;3.熟练掌握计算机系统的基本操作方法,了解如何编辑、编译、链接和运行一个C++程序;4.上机调试程序,掌握查错、排错使程序能正确运行。
三、实验的环境:硬件环境:处理器:Inter(R) Core(TM) i7-4500U内存:8.00GB软件环境:操作系统:Windows8.1编译软件:Microsoft Visual Studio 2012四、算法描述:我设计的带有括号的算术表达式求值的程序中,运算符的优先级是这样子的:1.先乘除,后加减2.同级运算从左到右依次运算。
3.先括号内的运算,再括号外的运算。
我的设计思路是,先输入一个最后不带等于号的中缀表达式,先对表达式检查是否有错误,如果有将会输出“表达式有错误”,否则通-2-过堆栈方法将这个中缀表达式转化为后缀表达式,然后将后缀表达式求值。
transform()——用于将中缀表达式转换为后缀表达式calculate()——将后缀表达式进行求值examine()——检查输入的表达式是否有错误main()——主程序。
五:源程序清单:#include<iostream>#include<cmath>#include<stack>#include<string>using namespace std;string transform(string str)//转换为后缀表达式{stack<char> ope;int i;string exp="";for(i=0;i<int(str.size());i++){if(str[i]=='.'||isdigit(str[i])){-4-exp+=str[i];}else if(str[i]=='+'||str[i]=='-'){int j=i-1;if(isdigit(str[j])){exp+=" ";//每个数字的后面都加一个空格加以区分if(ope.empty()||ope.top()=='('){ope.push(str[i]);}else{while(!ope.empty()&&ope.top()!='('){exp+=ope.top();ope.pop();}ope.push(str[i]);-5-}else{if(ope.empty()||ope.top()=='(') {ope.push(str[i]);}else{while(!ope.empty()&&ope.top()!='('){exp+=ope.top();ope.pop();}ope.push(str[i]);}}}else if(str[i]=='*'||str[i]=='/'||str[i]=='%')-6-int j=i-1;if(isdigit(str[j])){exp+=" ";if(ope.empty()||ope.top()=='('||ope.top()=='+'||ope.top( )=='-'){ope.push(str[i]);}else{while(!ope.empty()&&ope.top()!='('&&ope.top()!='+'&&ope.top ()!='-'){exp+=ope.top();ope.pop();}-7-ope.push(str[i]);}}else{if(ope.empty()||ope.top()=='('||ope.top()=='+'||ope.top( )=='-'){ope.push(str[i]);}else{while(!ope.empty()&&ope.top()!='('&&ope.top()!='+'&&ope. top()!='-'){exp+=ope.top();ope.pop();}-8-ope.push(str[i]);}}}//}else if(str[i]=='^') {int j=i-1;if(str[j]!=')'){exp+=" ";}ope.push(str[i]);}else if(str[i]=='(') {ope.push(str[i]);}else if(str[i]==')'){exp+=" ";while(ope.top()!='('){exp+=ope.top();ope.pop();}ope.pop();}else{return"有错误";}}while(!ope.empty())//遍历完表达式将堆栈中的所有运算符输出{if(isdigit(exp[exp.length()-1])){exp=exp+" "+ope.top();ope.pop();}else{exp=exp+ope.top();ope.pop();}}return exp;}int examine(string str)//检查输入的表达式是否有误{if((isdigit(str[str.length()-1])!=0||str[str.length()-1] ==')')&&(isdigit(str[0])!=0||str[0]=='+'||str[0]=='-'||str[ 0]=='(')){int i;for(i=0;i<int(str.length());i++){if(str[i]=='/'||str[i]=='%'||str[i]=='*'||str[i]=='^') {int a=i+1;if(str[a]=='/'||str[a]=='*'||str[a]=='%'||str[a]==')'||str[ a]=='.'){cout<<"表达式有错误"<<endl;return 1;break;}}else if(str[i]=='+'||str[i]=='-'){int a=i+1;if(str[a]=='/'||str[a]=='*'||str[a]=='%'||str[a]==')'||s tr[a]=='.'||str[a]=='^'){cout<<"表达式有错误"<<endl;return 1;break;}}else if(isdigit(str[i])!=0){int a=i+1;if(str[a]=='('){cout<<"表达式有错误"<<endl;return 1;break;}}elseif(isdigit(str[i])==0&&str[i]!='+'&&str[i]!='-'&&str[i]!='* '&&str[i]!='/'&&str[i]!='^'&&str[i]!='%'&&str[i]!='('&&str[ i]!=')'&&str[i]!='.'){cout<<"表达式有错误"<<endl;return 1;break;}else if(str[i]=='.'){int a=i+1;if(isdigit(str[a])==0){cout<<"表达式有错误"<<endl;return 1;break;}}while(i==str.length()-1){cout<<"表达式正确"<<endl;return 2;break;}}}elsecout<<"表达式有错误"<<endl;return 1;}double calculate(string exp){stack<double> number;double digit;string str="";for(int i=0;i<int(exp.length());i++) {if(isdigit(exp[i])||exp[i]=='.'){str=str+exp[i];}else if(exp[i]==' '){const char*p=str.c_str();digit=atof(p);//string转换为doublenumber.push(digit);str="";}else//(exp[i]!='.'&&exp[i]!=''&&!isdigit(exp[i])&&number.size()>=2){double result;double right;double left;right=number.top();number.pop();left=number.top();number.pop();switch(exp[i]){case'+':result=left+right;number.push(result);break;case'-':result=left-right;number.push(result);break;case'*':result=left*right;number.push(result);break;case'/':result=left/right;number.push(result);break;case'%':{int(result)=int(left)%int(right);number.push(result);b reak;}case'^':result=pow(left,right);number.push(result);break;}}}double finalresult=number.top();number.pop();return finalresult;}void main(){int x=1;cout<<"计算表达式"<<endl;cout<<"支持加+ 减- 乘* 除/ 整数取余% 次幂^ 小括号()"<<endl;while(x==1){string str;cout<<"请输入表达式,最后不加等号"<<endl;cin>>str;string exp;int a=examine(str);if(a==2){exp=transform(str);cout<<str<<"="<<calculate(exp)<<endl;}cout<<"继续运算请输入Y,否则按任意键退出"<<endl;char ch;cin>>ch;if(ch=='Y'||ch=='y'){x=1;}else{x=2;}}system("pause");}六、运行结果:这个是一开始运行的情况。