实验四 栈的应用---算术表达式的计算

合集下载

长沙理工大学数据结构栈的实现及应用算术表达式求值实验报告

长沙理工大学数据结构栈的实现及应用算术表达式求值实验报告

实验报告年级班号学号实验名称:栈的实现及其应用:算术表达式的计算实验日期2016年12月2日计算机科学与技术系2016年制一、实验环境32位操作系统下的Window平台Microsoft Visual C++二、实验目的掌握栈的实现及使用三、实验容1.实现栈的存储结构2.实现栈的基本操作的有关算法3.利用栈解决*算术表达式求值问题四、数据结构与算法思想描述顺序读取中缀表达式:1、当遇到数字时,将数字入数字栈2、当遇到操作符时,与操作符栈栈顶比较:If(当前操作符优先级大于操作符栈栈顶的优先级)If(非”)”操作符)将当前操作符进操作符栈;ElseWhile(操作符栈栈顶不等于”(“)取操作符栈栈顶及数字栈的两个数进行运算,并将结果压入数字栈;ElseIf(非(“操作符)While(操作符栈栈顶不等于”(“)取操作符栈栈顶及数字栈的两个数进行运算,并将结果压入数字栈;Continue;(直到当前操作符比栈顶操作符优先级大)Else将当前操作符进操作符栈;3、While(操作符栈非空)操作符栈栈顶及数字栈的两个数进行运算,并将结果压入数字栈;4、在数字栈取最后结果并输出。

五、程序清单//10*8^2+16.3+5*(5.2*5+3.01)/4-(-10)+0.1000060+4.00416-40 = 666.666666 //100+(-100)-(-10^2) = 100//(((2016-2017+(((2015-2014)))))) = 0//-1+(((((((((1^0))))))))+100%10^2 = 0#include<iostream>#include<stdio.h>#include<math.h>#include<string.h>#include<iomanip>#include<map>using namespace std;const int MAX = 105;typedef double Type;typedef struct{Type TypeStack[MAX];char charStack[MAX];int TypeTop, charTop;}Stack;//初始化栈void InitStack(Stack *S){S->charTop = S->TypeTop = 0; }//判断charStack是否为空bool IsEmpty_Char(Stack S){return S.charTop == 0;}//判断TypeStack是否为空bool IsEmpty_Type(Stack S){return S.TypeTop == 0;}//判断charStack是否为满bool IsFull_Char(Stack S){return S.charTop == MAX;}//判断TypeStack是否为满bool IsFull_Type(Stack S){return S.TypeTop == MAX;}void Push_Char(Stack *S, char ch){//charStack不为满则入栈,否则输出提示if(!IsFull_Char(*S))S->charStack[S->charTop++] = ch;elsecout << " The CharStack Is Full! " << endl; }void Push_Type(Stack *S, Type a){//TypeStack不为满则入栈,否则输出提示if(!IsFull_Type(*S))S->TypeStack[S->TypeTop++] = a;elsecout << " The TypeStack Is Full! " << endl; }char Pop_Char(Stack *S){if(!IsEmpty_Char(*S)){S->charTop--;return S->charStack[S->charTop];}elsecout << " The CharStack Is Empty! " << endl;return -1;}Type Pop_Type(Stack *S){if(!IsEmpty_Type(*S)){S->TypeTop--;return S->TypeStack[S->TypeTop];}elsecout << " The TypeStack Is Empty! " << endl;return -1;}char Top_Char(Stack S){if(!IsEmpty_Char(S))return S.charStack[--S.charTop];elsecout << " The CharStack Is Empty! " << endl;return -1;}Type Top_Type(Stack S){if(!IsEmpty_Type(S))return S.TypeStack[--S.TypeTop];elsecout << " The TypeStack Is Empty! " << endl;return -1;}Type Calculate(Type left, Type right, char op){Type value = 0;switch(op){case '+': value = left + right; break;case '-': value = left - right; break;case '*': value = left * right; break;case '/': if(right != 0)value = left / right;elsecout << "被除数不能为零!" << endl;break;case '%': i f(right != 0)value = (int)left % (int)right;elsecout << "被余数不能为零!" << endl;break;case '^': value = pow(left,right);/*value = 1;if(right >= 0)while(right--)value *= left;else{right = -right;while(right--)value /= left;}*/}return value;}void Computer(char *mid_equotion, Type len){Type right, left , result;char *p_mid_equotion = mid_equotion;char after_equotion = ' ';map<char,Type> Oper;Oper['#'] = 1; Oper['('] = 2; O per['+'] = 3;Oper['-'] = 3; O per['*'] = 4; Oper['/'] = 4;Oper['%'] = 4; Oper['^'] = 5; Oper[')'] = 6;Stack MyStack;InitStack(&MyStack);Push_Char(&MyStack,'#');char top_oper, current_oper;for(;*p_mid_equotion != '\0';){top_oper = Top_Char(MyStack);current_oper = *p_mid_equotion;if(!Oper[current_oper]){Push_Type(&MyStack,strtod(p_mid_equotion, &p_mid_equotion));continue;}//end ifelse //为操作符{if(Oper[current_oper] > Oper[top_oper]){if(current_oper != ')')Push_Char(&MyStack,current_oper);else{while(top_oper != '('){right = Pop_Type(&MyStack);if(!IsEmpty_Type(MyStack))left = Pop_Type(&MyStack);elseleft = 0;Push_Type(&MyStack,Calculate(left, right, Top_Char(MyStack)));Pop_Char(&MyStack);top_oper = Top_Char(MyStack);}Pop_Char(&MyStack);}//end else}//end ifelse{if(current_oper == '('){Push_Char(&MyStack,current_oper);if(*(p_mid_equotion + 1) == '-')Push_Type(&MyStack,0);}else{right = Pop_Type(&MyStack);if(!IsEmpty_Type(MyStack))left = Pop_Type(&MyStack);elseleft = 0;Push_Type(&MyStack,Calculate(left, right, top_oper));Pop_Char(&MyStack);continue;}}//end else}//end elsep_mid_equotion++;}//end fortop_oper = Pop_Char(&MyStack);while(top_oper != '#'){right = Pop_Type(&MyStack);if(!IsEmpty_Type(MyStack))left = Pop_Type(&MyStack);elseleft = 0;Push_Type(&MyStack,Calculate(left, right, top_oper));top_oper = Pop_Char(&MyStack);}// cout << setprecision(6) << "\nThe Result = " << (result = Pop_Type(&MyStack)) << endl;printf("The Result = %lf\n\n",(result = Pop_Type(&MyStack)));}int main(){char s[MAX] = "";Type i = 0;cout << "请输入你要求值的表达式!(以-1结束)\n";while(cin >> s && strcmp(s,"-1") != 0){Computer(s,strlen(s));cout << "请输入你要求值的表达式!(以-1结束)\n";}return 0;}六、程序执行结果及其分析对“+” , “-” , “*” , “/” , “%” , “^”运算的实现可运算多位数和小数,求余,求平方,括号里包含负数如(-1),及首个数字为负数如-1+1。

利用栈来实现算术表达式求值的算法

利用栈来实现算术表达式求值的算法

利用栈来实现算术表达式求值的算法利用栈来实现算术表达式求值的算法算术表达式是指按照一定规则组成的运算式,包含数字、运算符和括号。

在计算机中,求解算术表达式是一项基本的数学运算任务。

根据算术表达式的性质,我们可以考虑利用栈这一数据结构来实现求值算法。

一、算法思路首先,我们需要明确一个重要概念——逆波兰表达式(ReversePolish notation)。

逆波兰表达式是一种没有括号的算术表达式,其运算规则是先计算后面的数字和运算符,再计算前面的数字和运算符。

例如,对于算术表达式“3+4*5-6”,其对应的逆波兰表达式为“3 45 * +6 -”。

那么,我们可以利用栈来实现将中缀表达式转化为逆波兰表达式的过程,具体步骤如下:1. 创建两个栈——操作数栈和操作符栈。

2. 从左到右扫描中缀表达式的每一个数字和运算符,遇到数字则压入操作数栈中,遇到运算符则进行如下操作:(1)如果操作符栈为空或当前运算符的优先级大于栈顶运算符的优先级,则将当前运算符压入操作符栈中。

(2)如果当前运算符的优先级小于或等于栈顶运算符的优先级,则将栈顶运算符弹出并加入操作数栈中,重复此过程直到遇到优先级较低的运算符或操作符栈为空为止,然后将当前运算符压入操作符栈中。

3. 扫描完中缀表达式后,若操作符栈不为空,则将其中所有运算符弹出并加入操作数栈中。

4. 最终,操作数栈中存放的就是逆波兰表达式,我们可以按照逆波兰表达式的计算规则来计算其结果。

二、算法优点利用栈来实现算术表达式求值的算法具有以下优点:1. 代码简洁易懂,易于实现和维护。

2. 由于将中缀表达式转化为逆波兰表达式后,可以减少运算符的优先级关系而消除括号,从而减少求值的复杂度,提高程序的执行效率。

三、代码实现下面是利用栈来实现算术表达式求值的算法的Python代码实现:```pythonclass Stack:def __init__(self):self.items = []def push(self, item):self.items.append(item)def pop(self):return self.items.pop()def peek(self):return self.items[-1]def is_empty(self):return len(self.items) == 0def size(self):return len(self.items)def calculate(op_num1, op_num2, operator):if operator == "+":return op_num1 + op_num2elif operator == "-":return op_num1 - op_num2elif operator == "*":return op_num1 * op_num2elif operator == "/":return op_num1 / op_num2def infix_to_postfix(infix_expr):opstack = Stack()postfix_expr = []prec = {"+": 1, "-": 1, "*": 2, "/": 2, "(": 0} token_list = infix_expr.split()for token in token_list:if token.isdigit():postfix_expr.append(token)elif token == '(':opstack.push(token)elif token == ')':top_token = opstack.pop()while top_token != '(':postfix_expr.append(top_token)top_token = opstack.pop()else:while (not opstack.is_empty()) and(prec[opstack.peek()] >= prec[token]):postfix_expr.append(opstack.pop())opstack.push(token)while not opstack.is_empty():postfix_expr.append(opstack.pop())return " ".join(postfix_expr)def postfix_eval(postfix_expr):opstack = Stack()token_list = postfix_expr.split()for token in token_list:if token.isdigit():opstack.push(int(token))else:op_num2 = opstack.pop()op_num1 = opstack.pop()result = calculate(op_num1, op_num2, token) opstack.push(result)return opstack.pop()infix_expr = "3 + 4 * 5 - 6"postfix_expr = infix_to_postfix(infix_expr)print(postfix_expr)print(postfix_eval(postfix_expr))```四、总结算术表达式求值是一项常见的数学运算任务,利用栈这一数据结构来实现求值算法是一种简单有效的方法,它将中缀表达式转化为逆波兰表达式后,可以消除括号并减少运算符的优先级关系,从而提高程序的执行效率。

栈的运用实验报告

栈的运用实验报告

一、实验目的1. 理解栈的基本概念、特点及逻辑结构;2. 掌握栈的顺序存储和链式存储结构;3. 熟练掌握栈的基本操作,如入栈、出栈、判断栈空等;4. 理解栈在递归算法中的应用;5. 探究栈在实际问题中的应用。

二、实验内容1. 栈的定义与特点2. 栈的顺序存储结构3. 栈的链式存储结构4. 栈的基本操作5. 栈在递归算法中的应用6. 栈在实际问题中的应用三、实验步骤1. 栈的定义与特点(1)栈是一种后进先出(LIFO)的数据结构;(2)栈的元素只能从一端(栈顶)进行插入和删除操作;(3)栈具有两个基本操作:入栈和出栈。

2. 栈的顺序存储结构(1)使用数组来实现栈的顺序存储结构;(2)定义一个数组作为栈的存储空间;(3)定义栈顶指针top,初始值为-1;(4)定义栈的最大容量maxSize。

3. 栈的链式存储结构(1)使用链表来实现栈的链式存储结构;(2)定义一个链表节点,包含数据域和指针域;(3)定义栈顶指针top,初始时指向链表头节点。

4. 栈的基本操作(1)入栈操作:将元素插入到栈顶,栈顶指针向上移动;(2)出栈操作:删除栈顶元素,栈顶指针向下移动;(3)判断栈空:判断栈顶指针是否为-1,是则栈空,否则栈非空。

5. 栈在递归算法中的应用(1)斐波那契数列的递归算法;(2)汉诺塔问题;(3)迷宫问题。

6. 栈在实际问题中的应用(1)括号匹配问题;(2)表达式求值问题;(3)递归函数的调用栈。

四、实验结果与分析1. 栈的定义与特点通过本次实验,我们深入理解了栈的基本概念、特点及逻辑结构,掌握了栈的后进先出特性。

2. 栈的顺序存储结构使用数组实现栈的顺序存储结构,操作简单高效。

在实验过程中,我们实现了栈的基本操作,如入栈、出栈、判断栈空等。

3. 栈的链式存储结构使用链表实现栈的链式存储结构,具有灵活性和扩展性。

在实验过程中,我们实现了栈的基本操作,如入栈、出栈、判断栈空等。

4. 栈的基本操作通过实验,我们熟练掌握了栈的基本操作,如入栈、出栈、判断栈空等,为后续递归算法和实际问题中的应用奠定了基础。

栈的应用实验报告

栈的应用实验报告

栈的应用实验报告导言:在计算机科学领域中,数据结构是一项非常重要的基础。

栈是一种常用的数据结构,它在算法设计和软件开发中具有广泛的应用。

本实验旨在探索栈的应用,并通过实际操作来加深对栈数据结构的理解。

实验目的:1. 了解栈的定义和基本操作。

2. 掌握栈在实际问题中的应用方法。

3. 培养问题分析和解决的能力。

实验步骤:1. 实现栈的基本操作:压入(push)和弹出(pop)。

2. 针对以下实际问题,设计并实现相应的栈应用。

一、括号匹配问题括号匹配问题是指在一个字符串中,括号的开闭配对是否正确。

例如,"{[()]}"是正确的括号匹配,而"{[(])}"则是错误的括号配对。

通过使用栈,我们可以很方便地解决这个问题。

算法步骤如下:1. 遍历字符串的每个字符。

2. 若字符是左括号,则将其压入栈中。

3. 若字符是右括号,则检查栈是否为空,若为空则配对错误;若非空,则弹出栈顶元素并检查是否与右括号匹配。

4. 遍历结束后,若栈为空,则括号匹配正确,否则匹配错误。

二、函数调用问题在计算机程序中,函数的调用和返回遵循"先进后出"的原则,即后调用的函数先返回。

栈提供了一种便捷的方式来管理函数调用和返回过程。

在实际的编程中,我们可以使用栈来存储函数的局部变量和返回地址等信息。

例如,以下是一个简单的函数调用示例:1. 函数A调用函数B。

2. 函数B在栈中保存局部变量和返回地址。

3. 函数B执行完毕后,从栈中弹出局部变量和返回地址,程序继续执行函数A。

三、逆波兰表达式求值问题逆波兰表达式是一种不使用括号来表示表达式的方法,而是通过运算符放置在操作数之后的方式来表示。

例如,表达式"2 3 +"等价于中缀表达式"2 + 3"。

利用栈,我们可以很方便地对逆波兰表达式进行求值。

算法步骤如下:1. 遍历逆波兰表达式的每个元素。

2. 若元素是操作数,则将其压入栈中。

长沙理工大学数据结构栈的实现及应用算术表达式求值实验报告

长沙理工大学数据结构栈的实现及应用算术表达式求值实验报告

实验报告年级班号学号实验名称:栈的实现及其应用:算术表达式的计算实验日期2016年12月2日计算机科学与技术系2016年制一、实验环境32位操作系统下的Window平台Microsoft Visual C++二、实验目的掌握栈的实现及使用三、实验容1.实现栈的存储结构2.实现栈的基本操作的有关算法3.利用栈解决*算术表达式求值问题四、数据结构与算法思想描述顺序读取中缀表达式:1、当遇到数字时,将数字入数字栈2、当遇到操作符时,与操作符栈栈顶比较:If(当前操作符优先级大于操作符栈栈顶的优先级)If(非”)”操作符)将当前操作符进操作符栈;ElseWhile(操作符栈栈顶不等于”(“)取操作符栈栈顶及数字栈的两个数进行运算,并将结果压入数字栈;ElseIf(非(“操作符)While(操作符栈栈顶不等于”(“)取操作符栈栈顶及数字栈的两个数进行运算,并将结果压入数字栈;Continue;(直到当前操作符比栈顶操作符优先级大)Else将当前操作符进操作符栈;3、While(操作符栈非空)操作符栈栈顶及数字栈的两个数进行运算,并将结果压入数字栈;4、在数字栈取最后结果并输出。

五、程序清单//10*8^2+16.3+5*(5.2*5+3.01)/4-(-10)+0.1000060+4.00416-40 = 666.666666 //100+(-100)-(-10^2) = 100//(((2016-2017+(((2015-2014)))))) = 0//-1+(((((((((1^0))))))))+100%10^2 = 0#include<iostream>#include<stdio.h>#include<math.h>#include<string.h>#include<iomanip>#include<map>using namespace std;const int MAX = 105;typedef double Type;typedef struct{Type TypeStack[MAX];char charStack[MAX];int TypeTop, charTop;}Stack;//初始化栈void InitStack(Stack *S){S->charTop = S->TypeTop = 0; }//判断charStack是否为空bool IsEmpty_Char(Stack S){return S.charTop == 0;}//判断TypeStack是否为空bool IsEmpty_Type(Stack S){return S.TypeTop == 0;}//判断charStack是否为满bool IsFull_Char(Stack S){return S.charTop == MAX;}//判断TypeStack是否为满bool IsFull_Type(Stack S){return S.TypeTop == MAX;}void Push_Char(Stack *S, char ch){//charStack不为满则入栈,否则输出提示if(!IsFull_Char(*S))S->charStack[S->charTop++] = ch;elsecout << " The CharStack Is Full! " << endl; }void Push_Type(Stack *S, Type a){//TypeStack不为满则入栈,否则输出提示if(!IsFull_Type(*S))S->TypeStack[S->TypeTop++] = a;elsecout << " The TypeStack Is Full! " << endl; }char Pop_Char(Stack *S){if(!IsEmpty_Char(*S)){S->charTop--;return S->charStack[S->charTop];}elsecout << " The CharStack Is Empty! " << endl;return -1;}Type Pop_Type(Stack *S){if(!IsEmpty_Type(*S)){S->TypeTop--;return S->TypeStack[S->TypeTop];}elsecout << " The TypeStack Is Empty! " << endl;return -1;}char Top_Char(Stack S){if(!IsEmpty_Char(S))return S.charStack[--S.charTop];elsecout << " The CharStack Is Empty! " << endl;return -1;}Type Top_Type(Stack S){if(!IsEmpty_Type(S))return S.TypeStack[--S.TypeTop];elsecout << " The TypeStack Is Empty! " << endl;return -1;}Type Calculate(Type left, Type right, char op){Type value = 0;switch(op){case '+': value = left + right; break;case '-': value = left - right; break;case '*': value = left * right; break;case '/': if(right != 0)value = left / right;elsecout << "被除数不能为零!" << endl;break;case '%': i f(right != 0)value = (int)left % (int)right;elsecout << "被余数不能为零!" << endl;break;case '^': value = pow(left,right);/*value = 1;if(right >= 0)while(right--)value *= left;else{right = -right;while(right--)value /= left;}*/}return value;}void Computer(char *mid_equotion, Type len){Type right, left , result;char *p_mid_equotion = mid_equotion;char after_equotion = ' ';map<char,Type> Oper;Oper['#'] = 1; Oper['('] = 2; O per['+'] = 3;Oper['-'] = 3; O per['*'] = 4; Oper['/'] = 4;Oper['%'] = 4; Oper['^'] = 5; Oper[')'] = 6;Stack MyStack;InitStack(&MyStack);Push_Char(&MyStack,'#');char top_oper, current_oper;for(;*p_mid_equotion != '\0';){top_oper = Top_Char(MyStack);current_oper = *p_mid_equotion;if(!Oper[current_oper]){Push_Type(&MyStack,strtod(p_mid_equotion, &p_mid_equotion));continue;}//end ifelse //为操作符{if(Oper[current_oper] > Oper[top_oper]){if(current_oper != ')')Push_Char(&MyStack,current_oper);else{while(top_oper != '('){right = Pop_Type(&MyStack);if(!IsEmpty_Type(MyStack))left = Pop_Type(&MyStack);elseleft = 0;Push_Type(&MyStack,Calculate(left, right, Top_Char(MyStack)));Pop_Char(&MyStack);top_oper = Top_Char(MyStack);}Pop_Char(&MyStack);}//end else}//end ifelse{if(current_oper == '('){Push_Char(&MyStack,current_oper);if(*(p_mid_equotion + 1) == '-')Push_Type(&MyStack,0);}else{right = Pop_Type(&MyStack);if(!IsEmpty_Type(MyStack))left = Pop_Type(&MyStack);elseleft = 0;Push_Type(&MyStack,Calculate(left, right, top_oper));Pop_Char(&MyStack);continue;}}//end else}//end elsep_mid_equotion++;}//end fortop_oper = Pop_Char(&MyStack);while(top_oper != '#'){right = Pop_Type(&MyStack);if(!IsEmpty_Type(MyStack))left = Pop_Type(&MyStack);elseleft = 0;Push_Type(&MyStack,Calculate(left, right, top_oper));top_oper = Pop_Char(&MyStack);}// cout << setprecision(6) << "\nThe Result = " << (result = Pop_Type(&MyStack)) << endl;printf("The Result = %lf\n\n",(result = Pop_Type(&MyStack)));}int main(){char s[MAX] = "";Type i = 0;cout << "请输入你要求值的表达式!(以-1结束)\n";while(cin >> s && strcmp(s,"-1") != 0){Computer(s,strlen(s));cout << "请输入你要求值的表达式!(以-1结束)\n";}return 0;}六、程序执行结果及其分析对“+” , “-” , “*” , “/” , “%” , “^”运算的实现可运算多位数和小数,求余,求平方,括号里包含负数如(-1),及首个数字为负数如-1+1。

栈的应用——表达式求值

栈的应用——表达式求值

栈的应⽤——表达式求值 表达式求值是程序设计语⾔编译中的⼀个基本问题,它的实现就是对“栈”的典型应⽤。

本⽂针对表达式求值使⽤的是最简单直观的算法“算符优先法”。

本⽂给出两种⽅式来实现表达式求值,⽅式⼀直接利⽤中缀表达式求值,需要⽤到两个栈,操作数栈和操作符栈。

⾸先置操作数栈为空栈,操作符栈仅有“#”⼀个元素。

依次读⼊表达式中的每个字符,若是操作数则进操作数栈,若是操作符则和操作符栈的栈顶运算符⽐较优先权作相应操作,直⾄整个表达式求值完毕。

⽅式⼆⾸先把中缀表达式转换为后缀表达式并存储起来,然后利⽤读出的后缀表达式完成求值,其本质上是⽅式⼀的分解过程。

表达式求值的代码如下:#include <iostream>#include "stack"#include "map"using namespace std;/* 只能求⼀位整数的加减乘除混合运算 */map<char, pair<int, int>> priority; // 存放各个操作符的栈内栈外优先级,first是栈内,second是栈外char infix[50]; // 存放初始的中缀表达式char postfix[50]; // 存放转化的后缀表达式int result;void MakePriority() // 构造运算符优先级表{priority.insert(make_pair('#', make_pair(0, 0))); // isp(#)=0, icp(#)=0priority.insert(make_pair('\n', make_pair(0, 0))); // isp(\n)=0, icp(\n)=0 表达式结尾的'#'⽤'\n'代替,这样可以省略表达式末尾的结束符'#'priority.insert(make_pair('(', make_pair(1, 6))); // isp(()=1, icp(()=6priority.insert(make_pair('*', make_pair(5, 4))); // isp(*)=5, icp(*)=4priority.insert(make_pair('/', make_pair(5, 4))); // isp(/)=5, icp(/)=4priority.insert(make_pair('%', make_pair(5, 4))); // isp(%)=5, icp(%)=4priority.insert(make_pair('+', make_pair(3, 2))); // isp(+)=3, icp(+)=2priority.insert(make_pair('-', make_pair(3, 2))); // isp(-)=3, icp(-)=2priority.insert(make_pair(')', make_pair(6, 1))); // isp())=6, icp())=1}void InfixToPostfix() // 把中缀表达式转换为后缀表达式{int i = 0;stack<char> optrStack; // 操作符栈char optr; // optr为栈顶的操作符optrStack.push('#');while (!optrStack.empty()){if (isdigit(infix[i])) // 是操作数则直接输出(追加到postfix结尾){postfix[strlen(postfix)] = infix[i];postfix[strlen(postfix) + 1] = '\0';i++; // 读⼊中缀表达式的下⼀个字符}else// 是操作符, ⽐较优先级{optr = optrStack.top(); // 取出栈顶操作符if (priority[infix[i]].second > priority[optr].first) // icp(infix[i]) > isp(optr),infix[i]⼊栈{optrStack.push(infix[i]);i++;}else if (priority[infix[i]].second < priority[optr].first)// icp(infix[i]) < isp(optr),optr退栈并输出{postfix[strlen(postfix)] = optr;postfix[strlen(postfix) + 1] = '\0';optrStack.pop();}else// icp(infix[i]) = isp(optr),退栈但不输出,若退出的是'(',则继续读⼊下⼀个字符{optrStack.pop();if (optr == '(')i++;}}}}void CalculateByPostfix() // 通过后缀表达式求值{int i = 0;stack<int> opndStack; // 操作数栈int left, right; // 左右操作数int value; // 中间结果int newOpnd;while (postfix[i] != '#' && i < strlen(postfix)){switch (postfix[i]){case'+':right = opndStack.top(); // 从操作数栈中取出两个操作数opndStack.pop();left = opndStack.top();opndStack.pop();value = left + right;opndStack.push(value); // 中间结果⼊栈break;case'-':right = opndStack.top();opndStack.pop();left = opndStack.top();opndStack.pop();value = left - right;opndStack.push(value);break;case'*':right = opndStack.top();opndStack.pop();left = opndStack.top();opndStack.pop();value = left * right;opndStack.push(value);break;case'/':right = opndStack.top();opndStack.pop();left = opndStack.top();opndStack.pop();if (right == 0){cerr << "Divide by 0!" << endl;}else{value = left / right;opndStack.push(value);}break;default:newOpnd = (int)(postfix[i] - 48); // 操作数直接⼊栈opndStack.push(newOpnd);break;}i++;}result = opndStack.top();}void CalculateByInfix() // 直接利⽤中缀表达式求值{int i = 0;stack<char> optrStack; // 操作符栈stack<int> opndStack; // 操作数栈char optr; // optr为操作符栈顶的操作符int left, right, value; // 左右操作数以及中间结果optrStack.push('#');optr = optrStack.top();while (!optrStack.empty()) // 直到操作符栈为空{if (isdigit(infix[i])) // 是操作数, 进操作数栈{value = (int)(infix[i] - 48);opndStack.push(value);i++;}else// 是操作符, ⽐较优先级{optr = optrStack.top(); // 取出操作符栈顶的操作符if (priority[infix[i]].second > priority[optr].first) // icp(infix[i]) > isp(optr),infix[i]⼊栈 {optrStack.push(infix[i]);i++;}else if (priority[infix[i]].second < priority[optr].first) // icp(infix[i]) < isp(optr),optr退栈并输出{optrStack.pop();right = opndStack.top(); // 从操作数栈中取出两个操作数opndStack.pop();left = opndStack.top();opndStack.pop();switch (optr){case'+':value = left + right;opndStack.push(value); // 中间结果⼊栈break;case'-':value = left - right;opndStack.push(value); // 中间结果⼊栈break;case'*':value = left * right;opndStack.push(value); // 中间结果⼊栈break;case'/':if (right == 0){cerr << "Divide by 0!" << endl;}else{value = left / right;opndStack.push(value);}break;default:break;}}else{optrStack.pop();if (optr == '(')i++;}}}result = opndStack.top();}int main(){MakePriority(); // 构造运算符优先级表cout << "请输⼊中缀表达式:";cin >> infix;cout << "直接利⽤中缀表达式求值为:";CalculateByInfix();cout << result << endl;cout << "转化为后缀表达式:";InfixToPostfix();for (int i = 0;i < strlen(postfix);i++){cout << postfix[i];}cout << endl;cout << "利⽤后缀表达式求值为:";CalculateByPostfix();cout << result << endl;return0;} 为了⽅便起见,本⽂只是简单的设计了⼀个针对⼀位整数的四则运算进⾏求值的算法,对于处理多位整数的四则运算,需要对本⽂接受输⼊的数据类型进⾏“升阶”,把字符数组换成字符串数组,将⼀个整数的多位数字存⼊⼀个字符串进⾏处理。

实验栈应用算术表达式计算

实验栈应用算术表达式计算

浙江大学城市学院实验报告课程名称_________ 数据结构与算法实验工程名称实验四栈的应用---算术表达式的计算学生姓名专业班级学号实验成绩指导老师<签名)日期一.实验目的和要求1•进一步掌握栈的基本操作的实现。

2•掌握栈在算术表达式的计算方面的应用。

二.实验内容1.编写程序对后缀表达式进行求值<利用栈),即输入任一个后缀表达式,输出该后缀表达式的值。

要求:把栈的基本操作的实现函数存放在文件stack.h 中,在主程序文件test4.cpp中包含后缀表达式求值函数doubleCompute(char *str>与主函数。

主函数可以参考如下:void mai n(>{char str[50]。

printf("请输入一个后缀表达式:">。

gets(str>。

printf("后缀表达式值为:%f\n", Compute(str> > 。

}2 .填写实验报告,实验报告文件取名为report4.doc。

3. 上传实验报告文件report4.doc与源程序文件stack.h及test4.cpp到Ftp服务器上你自己的文件夹下。

三.函数的功能说明及算法思路包括每个函数的功能说明,及一些重要函数的算法实现思路void Change( char *S1, char *S2 >中缀表达式转化为后缀表达式double Compute(char *str>::后缀表达式求值void InitStack (Stack &S> 初始化栈Int EmptyStack (Stack S>判断栈是否为空void Push(Stack &S, ElemType item:入栈ElemType Pop(Stack &S> 出栈ElemType Peek(Stack S> 取栈顶元素void ClearStack (Stack &S> 清除栈四.实验结果与分析包括运行结果截图等五■心得体会记录实验感受、上机过程中遇到的困难及解决办法、遗留的问题、意见和建议等。

数据结构实验二——算术表达式求值实验报告

数据结构实验二——算术表达式求值实验报告

数据结构实验二——算术表达式求值实验报告算术表达式求值实验报告一、引言算术表达式求值是计算机科学中一个重要的基础问题,它涉及到了数据结构和算法的应用。

本实验旨在通过实现一个算术表达式求值的程序,加深对数据结构中栈的理解和应用,并掌握算术表达式的求值过程。

二、实验目的1. 理解算术表达式的基本概念和求值过程;2. 掌握栈的基本操作和应用;3. 实现一个能够正确求解算术表达式的程序;4. 进一步熟悉编程语言的使用。

三、实验内容1. 设计并实现一个栈的数据结构;2. 实现算术表达式求值的算法;3. 编写测试用例,验证程序的正确性;4. 进行性能测试,分析算法的时间复杂度。

四、实验方法与步骤1. 设计栈的数据结构在本实验中,我们选择使用数组来实现栈的数据结构。

栈的基本操作包括入栈(push)、出栈(pop)、判断栈空(isEmpty)和获取栈顶元素(top)等。

2. 算术表达式求值算法算术表达式求值的一种常用算法是通过后缀表达式进行求值。

具体步骤如下: - 将中缀表达式转换为后缀表达式;- 通过栈来求解后缀表达式;- 返回最终的计算结果。

3. 编写测试用例编写一系列测试用例,包括不同类型的算术表达式,以验证程序的正确性。

例如:- 简单的四则运算表达式:2 + 3 * 4 - 5;- 包含括号的表达式:(2 + 3) * (4 - 5);- 包含多位数的表达式:12 + 34 * 56;- 包含浮点数的表达式:3.14 + 2.71828。

4. 性能测试和时间复杂度分析针对不同规模的输入数据,进行性能测试,记录程序的运行时间。

同时,分析算法的时间复杂度,验证算法的效率。

五、实验结果与分析我们设计并实现了一个栈的数据结构,并成功地完成了算术表达式求值的程序。

通过对一系列测试用例的验证,我们发现程序能够正确地求解各种类型的算术表达式,并返回正确的计算结果。

在性能测试中,我们对不同规模的输入数据进行了测试,并记录了程序的运行时间。

栈的应用实验报告

栈的应用实验报告

栈的应用实验报告栈的应用实验报告引言:栈是一种常见的数据结构,它具有后进先出(Last In First Out,LIFO)的特点。

在计算机科学中,栈被广泛应用于各种领域,如编译器、操作系统、图形处理等。

本实验旨在通过实际应用场景,探索栈的应用。

一、栈的基本概念和操作栈是一种线性数据结构,它由一系列元素组成,每个元素都有一个前驱元素和一个后继元素。

栈的基本操作包括入栈(Push)和出栈(Pop)。

入栈将元素添加到栈的顶部,而出栈则将栈顶元素移除。

此外,栈还具有查看栈顶元素(Top)和判断栈是否为空(IsEmpty)的操作。

二、栈在表达式求值中的应用栈在表达式求值中发挥着重要作用。

例如,当我们需要计算一个数学表达式时,可以通过将表达式转换为后缀表达式,并利用栈来进行求值。

栈中存储操作数,当遇到运算符时,从栈中弹出相应数量的操作数进行计算,再将结果入栈。

通过这种方式,我们可以实现高效的表达式求值。

三、栈在函数调用中的应用栈在函数调用中也扮演着重要角色。

当我们调用一个函数时,计算机会将函数的返回地址、参数和局部变量等信息存储在栈中。

这样,当函数执行完毕后,可以从栈中恢复之前的上下文,继续执行调用函数的代码。

栈的这种特性使得递归函数的实现成为可能,同时也为程序的模块化提供了便利。

四、栈在迷宫求解中的应用栈在迷宫求解中也能发挥重要作用。

当我们需要找到从起点到终点的路径时,可以利用栈来存储当前路径上的位置。

从起点开始,我们按照某种策略选择下一个位置,并将其入栈。

如果当前位置无法继续前进,则将其出栈,并选择下一个位置。

通过不断重复这个过程,直到找到终点或者栈为空,我们就能得到迷宫的解。

五、栈在撤销和恢复操作中的应用栈在撤销和恢复操作中也能发挥重要作用。

当我们在编辑文档或者绘图时,经常需要进行撤销和恢复操作。

栈可以用来记录每次操作的状态,当用户选择撤销时,从栈中弹出最近的操作,并将文档或图形恢复到之前的状态。

通过这种方式,我们可以提供良好的用户体验,同时也方便用户进行操作的回溯。

实验4栈的实现和应用

实验4栈的实现和应用

陕西科技大学实验报告姓名班级学号实验组别实验日期室温报告日期成绩报告内容:(目的和要求、原理、步骤、数据、计算、小结等)一、实验名称:栈的实现与应用二、实验目的:1.掌握栈的定义。

2.掌握栈基本操作的实现,并能用于解决实际问题。

三、实验环境:Windows2000,Visual C++ 6.0四、实验内容:1.实现栈的如下基本操作:push,pop,isempty,isfull,createstack。

2.利用栈的基本操作实现conversion()函数,该函数能将任意输入的十进制整数转换为二进制形式表示。

五、实验原理:1.栈的基本概栈(stack)是一种特殊的线性表。

是将线性表的插入和删除均是仅在表的一端进行,通常将允许插入和删除的一端称栈顶(Top),因此栈顶的当前位置是动态变化的,它由一个称为栈顶指针的位置指示器指示。

同时,表的一端称栈底(Bottom)。

当栈中没有元素时称为空栈。

栈的插入操作被形象的称为进栈或入栈,删除操作称为出栈或退栈。

2.栈的结构特性通常栈可以用线性的方式存储,分配一块连续的存储区域存放栈中的元素,并用一个变量指向当前的栈顶。

每次进栈的元素都被放在原栈顶元素之上而成为新的栈顶,而每次出栈的总是当前栈中“最新”的元素,即最后进栈的元素。

元素是以a1,a2,a3,...,an的顺序进栈的,而退栈的次序却是an,...,a3,a2,a1。

栈的修改是按后进先出的顺序进行的。

因此,栈又称为后进先出的线性表,简称为LIFO表.3.栈的建立C语言中用一维数组来实现栈.假设栈的元素个数最大不超过Maxsize,所有的元素都具有同一个数据类datatype,则可以用下列方式来定义栈的类型stack:typedef struct{datatype elements[maxsize];int Top;}Stack;4.栈的压入(push)void push(ST,x)stak *ST ;ElemType x;{if(ST->top==Maxsize-1)printf(“栈上溢出!\n”);else{ST->top++;ST->s[ST->top]=x;}}5.栈的弹出pop(ST)void pop(ST,x)stak *ST ;{if(ST->top==-1)printf(“栈上溢出!\n”);elseST->top--;}6.判断栈是否为空(isempty)int sempty(ST)stack *ST;{if(ST->top==-1)return(1);elsereturn(0)}7.读栈顶元素top(ST,x)Void pop(ST,x)Stack *STElemType *x;{If(ST->top==-1)printf(“无栈顶元素!\n”);else *x=ST->s[ST->top];}8.取栈顶元素ptop(ST)ElemType ptop(ST)Stack *ST;{Elemtype x; /*将栈顶元素赋给x*/top (ST,&x); /* 将栈顶元素弹出*/pop(ST); /*返回x值*/return(x);}五.实验流程:六.程序代码#include<stdio.h>#include<stdlib.h>#define maxsize 1024typedef int datatype;typedef struct{datatype elements[maxsize];int Top;}Stack;void setNull(Stack *S){S->Top=-1;}int isfull(Stack *S){if(S->Top>=maxsize-1)return(1);else return(0);}int isempty(Stack *S){if(S->Top>=0)return(0);else return(1);}void push(Stack *S,datatype E){if(S->Top>=maxsize-1){printf("Stack Overflow");}else{S->Top++;S->elements[S->Top]=E;}}datatype *pop(Stack *S){datatype *temp;if(isempty(S)){printf("Stack Underfiow");return(NULL);}else{S->Top--;temp=(datatype *)malloc(sizeof(datatype));*temp=S->elements[S->Top+1];return(temp);}}void conversion(int n){int r,m;Stack S;setNull(&S);r=n;while(r){m=r%2;if(isfull(&S))printf("Over flow\n");else push(&S,m);r=r/2;}printf("转换后的二进制为\n");while(!isempty(&S))printf("%d",*(pop(&S)));printf("\n");}void main(){int num;printf("请输入需要转换为二进制的十进制数据\n");scanf("%d",&num);conversion(num);}七.实验截图八.实验小结此次上机实验,我不仅对栈的存储等操作有了一定的认识,也对十进制到二进制的转换有了深刻的理解,同时对编译程序的算法思想有了新的认识,还让我深刻的体会到了链表的重要性以及其应用的方便,并且对指针加深了印象,应用了书本中的算法思想,对我以后的编译以及完成新的程序有很大的帮助。

用栈计算数学表达式的值

用栈计算数学表达式的值

实验4 用栈计算表达式的值一、问题描述实现栈,并基于栈求表达式的值。

二、需求分析1、简述程序的基本功能将输入的一个表达式转化为后缀式,并计算该算式的值。

2、输入的形式和输入值的范围输入的必须是一个整型算式,可以包含加减乘除以及小括号。

运算完成后,提示输入Y/N,输入为字符型,用以判断是否继续运算。

3、输出的形式每一次运算后,输出运算结果为整型。

4、测试数据要求要求输入的必须为运算式,即只能有整型数字加减乘除以及小括号。

三、概要设计1、抽象数据类型有一个类class stack,它含有三个数据成员:*element 、top、maxsize;分别表示栈中元素、栈顶位置、栈的容量。

还有几个成员函数用来进行进栈、出栈、取出栈顶元素、判断栈是否为空等操作。

2、主程序流程及模块调用关系a) 定义char型指针变量s1,并为之申请了100个数据的空间;b) 用while循环语句开始运行程序;c) 键盘输入s1,即数学表达式;d) 程序运算并输出结果,然后提示是否继续运算,请求输入字符Y/N; e) 输入y 或Y时,程序继续进行while循环,进行运算;输入n或N时,程序结束;若输入其他字符,提示输入错误,要求重新输入。

四、详细设计(要求主要变量和语句加注释)1、抽象数据类型的实现:包括类型定义和各个操作的实现。

#include<iostream> using namespace std;template<class T>class stack{public:stack(int sz=100);~stack(){delete[]element;};bool push(T x);bool pop(T &x);bool getTop(T &x);bool IsEmpty(){return top==-1?true:false;}; bool Full(){return top==maxsize-1?true:false;}; int getsize(){return top+1;};private:T *element;int top;int maxsize;};template<class T>stack<T>::stack(int sz){top=-1;maxsize=sz;element=new T[maxsize];}template<class T>bool stack<T>::push(T x){if(Full())return false;else element[++top]=x;return true;}template<class T>bool stack<T>::pop(T &x){if(IsEmpty())return false;else x=element[top--];return true;}template<class T>bool stack<T>::getTop(T &x){if(IsEmpty())return false;elsex=element[top];return true;}2、主程序的实现#include"Stack.h"#include"string.h"#include<iostream>using namespace std;bool IsOperator(char ch){if(ch=='+'||ch=='-'||ch=='*'||ch=='/')return true; else return false; }int judge(char ch){if(ch=='+'||ch=='-')return 1;else if(ch=='*'||ch=='/')return 2;else if(ch=='('||ch=='#')return 0;}int cal(int n1,int n2,char ch){if(ch=='+')return n1+n2;else if(ch=='-')return n1-n2;else if(ch=='*')return n1*n2;else if(ch=='/')return n1/n2;}char *postfix(char *s1){int i=0,j=0;char *s2=new char[2*strlen(s1)],ch=s1[0],c;stack<char>cs;cs.push('#');while(ch!='\0'){if(IsOperator(ch)){if(s2[j-1]!=' '&&!IsOperator(s2[j-1]))s2[j++]=' '; cs.getTop(c); if(judge(ch)>judge(c)){cs.push(ch); }else{cs.pop(c); s2[j++]=c; i--;}}if(ch=='('){cs.push(ch);}if(ch==')'){s2[j++]=' ';cs.pop(c);while(c!='('){s2[j++]=c; cs.pop(c); }}if(ch>='0'&&ch<='9') {s2[j++]=ch;}i++;ch=s1[i];}if(!IsOperator(s2[j-1]))s2[j++]=' '; cs.pop(c); while(c!='#'){s2[j++]=c;cs.pop(c);}s2[j]='\0';return s2;}int cal_post(char *s){stack<int>ints;char ch=s[0];while(ch!='\0'){if(ch<='9'&&ch>='0')t=t*10+ch-'0';if(ch==' '){ints.push(t);t=0;}if(IsOperator(ch)){int n1,n2;ints.pop(n2);ints.pop(n1);ints.push(cal(n1,n2,ch));}i++;ch=s[i];}ints.pop(t);return t;}void main(){char *s1=new char [100],*s2,x;bool a=true,b;while(a){b=true;cout<<"请输入要计算的式子:"; cin>>s1;s2=postfix(s1);cout<<s1<<"="<<cal_post(s2)<<endl; cout<<"是否继续计算?(Y/N)";{cin>>x;if(x=='n'||x=='N'){a=false;b=false;}else if(x=='y'||x=='Y')b=false;else{cout<<"输入错误!请重新输入:";b=true;} }delete []s2;}delete []s1;}五、调试分析1、设计与调试过程中遇到的问题及分析、体会遇到的最大的问题就是:动态申请的空间不知道应该什么时候释放,开始时一直出现这种问题,后来请教同学,又问了老师,才完全把这一问题解决。

栈的应用—算术表达式求值

栈的应用—算术表达式求值

栈的应⽤—算术表达式求值例三、算术表达式求值1、问题描述当⼀个算术表达式中含有多个运算符,且运算符的优先级不同的情况下,如何才能处理⼀个算术表达式2、思路⾸先我们要知道表达式分为三类:①中缀表达式:a+(b-c/d)*e②前缀表达式+a*-be③后缀表达式abcd/-e*+由于运算符有优先级,所以在计算机中计算⼀个中缀的表达式⾮常困难,特别是带括号的更⿇烦,⽽后缀表达式中既⽆运算符优先⼜⽆括号的约束问题因为在后缀表达式中运算符出现的顺序正是计算的顺序,所以计算⼀个后缀的表达式更简单。

所以,可以将求算术表达式的值的过程化成两个过程:1.将⼀个中缀表达式化成⼀个后缀表达式2.对后缀表达式进⾏求值⼀、将中缀变成⼀个后缀因为要将运算符出现的次序与真正的算术运算顺序⼀直,所以,就要让优先级⾼的以及括号内的运算符出现在前⾯,因此要使⽤⼀个栈来保留还未送往后缀表达式的运算符,此栈称为运算符栈算法描述如下:(1)初始化⼀个运算符栈(2)从算术表达式输⼊的字符串中,从左到右的读取⼀个字符(3)若当前的字符是操作数,则直接送往后缀表达式(4)若当前的字符是左括号,则将其压⼊运算符栈(5)若当前的字符是操作符,则进⾏如下操作:①当运算符栈为空时,直接将其压⼊栈。

②当此运算符的优先级⾼于栈顶的运算符时,则将此运算符压⼊栈,否则,弹出栈顶运算符送往后缀式,并将当前运算符压栈,重复步骤(5)(6)若当前字符是右括号,反复将栈顶符号弹出,并送往后缀表达式中,知道栈顶元素为左括号为⽌,然后将左括号出栈并丢弃(7)若读取还未结束,则重复步骤(2)(8)若读取结束,则将栈中剩余的所有的运算符弹出并送往后缀表达式⼆、计算后缀表达式的值计算步骤很简单,就是找到运算符,然后找前⾯最后出现的两个操作数,从⽽构成⼀个最⼩的算术表达式进⾏运算,在计算过程中也需要利⽤⼀个栈来保留后缀表达式中还未参与运算的操作数,称为操作数栈,算法描述如下:(1)初始化⼀个操作数栈(2)从左到右依次读⼊后缀表达式中的字符①若当前字符是操作数,则压⼊操作数栈。

关于栈的实验报告

关于栈的实验报告

关于栈的实验报告引言栈(Stack)是一种常用的数据结构,它基于后进先出(Last In First Out,LIFO)的原则,元素的插入和删除操作只能在栈顶进行。

栈具有快速插入和删除元素的特点,因此在很多应用中广泛使用。

本实验旨在通过编写一个栈的实现,探究栈的基本操作以及应用,并对栈的性能进行评估。

一、栈的实现1. 栈的定义使用数组来实现一个基本的栈结构,可以定义一个栈类`Stack`,其中包含以下属性和方法:- 属性:- `max_size`:栈的最大容量- `top`:栈顶指针- `data`:存储栈元素的数组- 方法:- `__init__(self, size)`:构造函数,初始化栈对象,参数为栈的最大容量- `is_empty(self)`:判断栈是否为空- `is_full(self)`:判断栈是否已满- `push(self, item)`:将元素压入栈顶- `pop(self)`:从栈顶弹出一个元素- `peek(self)`:返回栈顶元素- `size(self)`:返回栈的当前大小- `clear(self)`:清空栈中所有元素2. 栈的实现pythonclass Stack:def __init__(self, size):self.max_size = sizeself.top = -1self.data = [None] * sizedef is_empty(self):return self.top == -1def is_full(self):return self.top == self.max_size - 1 def push(self, item):if self.is_full():print("Stack is full.")returnself.top += 1self.data[self.top] = itemdef pop(self):if self.is_empty():print("Stack is empty.")return Noneitem = self.data[self.top]self.top -= 1return itemdef peek(self):if self.is_empty():print("Stack is empty.")return Nonereturn self.data[self.top]def size(self):return self.top + 1def clear(self):self.top = -1上述代码实现了一个基本的栈,其中使用一个列表`data` 来存储栈的元素,`top` 表示栈顶指针,初始值为-1。

栈的应用实验报告

栈的应用实验报告

栈的应用实验报告实验目的:1.了解栈结构及其应用;2.通过实验加深对栈的理解;3.掌握栈的基本操作。

实验内容:1.实现栈的基本功能,包括入栈、出栈、获取栈顶元素、判断栈是否为空等;2.实现一些特殊功能,如:计算表达式的值、判断括号是否匹配等;3.应用栈实现前缀、中缀、后缀表达式之间的转换。

实验步骤:1.首先实现栈的基本功能,根据题目需求选择相应的数据结构,如:数组、链表等,我选择了数组。

定义栈的数据结构,包括:栈顶指针、栈的大小、栈中元素的个数等信息;2.实现入栈操作,即向栈中添加元素;3.实现出栈操作,从栈中取出元素;4.实现获取栈顶元素的操作,即查看栈顶元素,但不从栈中删除;5.实现判断栈是否为空的操作;6.实现计算表达式的值的操作。

7.实现括号匹配判断操作。

8.应用栈实现前缀、中缀、后缀表达式之间的转换。

实验结果:1.通过实验,我能够熟练掌握栈的基本操作,如入栈、出栈、获取栈顶元素、判断栈是否为空等。

2.通过对表达式的求值,我能够了解栈在计算机科学中的重要应用,能够解决表达式中优先级问题。

3.通过对括号匹配的判断,我能够更好地理解栈的后进先出的特性。

4.应用栈实现前缀、中缀、后缀表达式之间的转换,我能够更好地理解这三种表达式的区别,以及更好地理解栈的应用。

结论:通过这次实验,我对栈的理解更深入了。

栈是一种非常重要的数据结构,在计算机领域有着广泛的应用,如编译器、表达式计算、括号匹配等。

因此,掌握和熟练应用栈是非常有必要的。

希望以后在学习计算机相关知识的时候,能够多加使用和练习栈的相关操作。

栈的应用实验报告

栈的应用实验报告

数据结构实验报告报告名称栈的应用专业网络工程班级1001学号************姓名张剑指导教师陈淑红李珍辉黄哲2012 年5 月4日一、实验目的:熟练掌握栈的基本操作,进一步理解栈的应用。

二、实验内容与基本要求:实验内容:设计一个程序,用算符优先法对算术表达式求值基本要求:以字符序列的形式从终端输入语法正确的、不含变量的算术表达式,利用算符优先关系,实现对算术四则混合运算表达式求值。

三、实现提示:1.利用栈辅助分析算符优先关系;2.在读入表达式字符序列的同时,完成运算符和操作数的识别处理,以及相应的运算;3.在识别出操作数的同时,要将其字符序列形式转换成相应的浮点数形式。

四.概要设计:1.顺序栈的定义:typedef struct{SElemType *base;SElemType *top;int stacksize;} SqStack;2.栈的基本操作:InitStack(&S)操作结果:构造一个空栈S。

DestoryStack(&S)初始条件:栈S存在。

、操作结果:栈S被销毁。

ClearStack(&S)初始条件:栈S存在。

、操作结果:将S清为空栈。

StackEmpty(&S)初始条件:栈S存在。

、操作结果:若S为空栈,则返回TUUE,否则FALSE.StackLength(&S)初始条件:栈S存在。

、操作结果:返回S的元素个数,即栈的长度。

GetTop(S,&e)初始条件:栈S存在且非空。

操作结果:用e 返回S的栈顶元素。

Push(&S,e)初始条件:栈S存在。

、操作结果:插入元素e为新的栈顶元素。

pop (&s,&e)初始条件:栈S存在且非空。

操作结果:删除S的栈顶元素,并用e返回其值。

StackTravse(S,vist())初始条件:栈S存在且非空.操作结果:从栈底到栈顶依次对S的每个元素调用函数vist(),一旦vist()失败,择操作结束。

栈 四则运算

栈 四则运算

栈四则运算
栈四则运算是计算机科学中的一个基本算法,它利用栈来实现表达式的计算。

在栈四则运算中,我们需要将表达式中的数字和运算符依次入栈,并在遇到运算符时弹出相应的数字进行计算,最终得到表达式的结果。

这种算法的优点在于它能够处理复杂的表达式,并且具有较高的运算效率。

同时,栈四则运算也是许多计算机程序设计语言的基础之一,例如C语言中的表达式计算、Java中的算术运算等。

然而,在实际应用中,栈四则运算也存在一些问题。

例如,当表达式中存在括号时,需要进行额外的处理才能得到正确的结果。

由于计算机存储空间的限制,对于过于复杂的表达式,栈的深度可能会超过系统所能承受的范围,从而导致程序崩溃。

总的来说,栈四则运算是计算机科学中一项重要的算法,它在实际应用中具有广泛的应用。

然而,在使用时需要注意其局限性,以保证程序的正确性和稳定性。

栈的应用——表达式计算

栈的应用——表达式计算

栈的应用——表达式计算保定二中刘中一一、中缀表达式和后缀表达式后缀表达式的优点就是可以忽略表达式中的算符优先级。

二、相关的语言知识三、布尔型、字符型、ASCII码以及互转、子界型、集合类型、判断语句的CASE、字符串四、表达式计算例题一例如后缀表达式输入为7 2 + 4 - (每个数都是个位,运算符号只是加减乘除,没有括号)代码如下:varstack:array[0..1000] of integer;s:string;i,top,x,y,z:integer;beginassign(input,'d:\bds.in');reset(input);assign(output,'d:\bds.out');rewrite(output);readln(s);top:=0;i:=0;repeatinc(i);if s[i] in ['0'..'9'] thenbegin inc(top); stack[top]:=ord(s[i])-ord('0'); end;if s[i]='+' thenbeginy:=stack[top];dec(top);x:=stack[top];z:=x+y;stack[top]:=z;end;if s[i]='-' thenbeginy:=stack[top];dec(top);x:=stack[top];z:=x-y;stack[top]:=z;end;until i=length(s);writeln(stack[1]);close(input);close(output);end.测试:3*(5-2)+7五、表达式计算例题二78 12 + 2 / (数值任意位数)代码如下:varstack:array[0..1000] of integer;s:string;ch:char;i,top,x,y,z:integer;beginassign(input,'d:\bds.in');reset(input);assign(output,'d:\bds.out');rewrite(output); readln(s);top:=0;i:=0;repeatinc(i);if s[i] in ['0'..'9'] thenbeginx:=0;ch:=s[i];while ch<>' ' dobeginx:=x*10+ord(s[i])-ord('0');inc(i);ch:=s[i];end;inc(top);stack[top]:=x;end;if s[i]='+' thenbeginy:=stack[top];dec(top);x:=stack[top];z:=x+y;stack[top]:=z;end;if s[i]='-' thenbeginy:=stack[top];dec(top);x:=stack[top];z:=x-y;stack[top]:=z;end;if s[i]='*' thenbeginy:=stack[top];dec(top);x:=stack[top];z:=x*y;stack[top]:=z;end;if s[i]='/' thenbeginy:=stack[top];if y=0 then begin writeln('error'); close(input);close(output);halt;end;dec(top);x:=stack[top];stack[top]:=z;z:=trunc(x/y);end;until i=length(s);writeln(stack[1]);close(input);close(output);end.。

实验4 栈的应用

实验4  栈的应用

数据结构实验报告实验名称:实验4——栈的应用学生姓名:班级:班内序号:15学号:日期:2015年12月28日1.实验要求表达式求值是程序设计语言编译中最近本的问题,它要求把一个表达式翻译成能够直接求值的序列。

例如用户输入字符串“14+((13-2)*2-11*5)*2”,程序可以自动计算得到最终的结果。

在这里,我们将问题简化,假定算数表达式的值均为非负整数常数,不包含变量、小数和字符常量。

试设计一个算术四则运算表达式求值的简单计算器。

基本要求:1、操作数均为非负整数常数,操作符仅为+、-、*、/、(和);2、编写main函数进行测试。

2.1 存储结构顺序栈:int型数字栈char型字符栈Top=-1 Top=-12.2 关键算法分析1.判断输入字符是否为运算符int IsOpr(char c) //判断输入字符是否为运算符{if (c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='#')return 1;elsereturn 0;}2.判断字符的优先级将判断条件分为多种情况:如果栈顶元素是+、-的情况与刚取得的字符大小比较如果是+、-则返回>,如果是*、/则返回<,如果是左括号则返回<,如果是右括号则返回>,其他情况则返回> 如果栈顶元素是*、/的情况与刚取得的字符大小比较如果是+、-则返回>,如果是*、/则返回>,如果是左括号则返回<,如果是右括号则返回>,其他情况则返回> 如果栈顶元素是(的情况与刚取得的字符大小比较,除了右括号是=以外,其他都是返回<如果栈顶元素是)的情况与刚取得的字符大小比较,都是返回>如果栈顶元素是#的情况与刚取得的字符大小比较,除了#返回=以外,其他都是返回> 这个方法即将中序表达式转换为后缀表达式char Precede(char s,char c) //判断字符的优先级{switch(s){case '+':case '-':{if(c=='+'||c=='-')return '>';else if (c=='*'||c=='/')return '<';else if(c=='(')return '<';else if(c==')')return '>';elsereturn '>';}break;case '*':case '/':{if(c=='+'||c=='-')return '>';else if (c=='*'||c=='/')return '>';else if(c=='(')return '<';else if(c==')')return '>';elsereturn '>';}break;case '(':{if(c==')')return '=';elsereturn '<';}break;case ')':{return '>';}break;case '#':{if(c=='#')return '=';elsereturn '<';}break;}}3.计算int Operate(int x,char opr,int y) //计算{int result;switch (opr){case '+':result = x + y;break;case '-':result = x - y;break;case '*':result = x * y;break;case '/':result = x / y;break;}return result;}3. 程序运行结果程序运行图源代码:#include<iostream> #include<string> using namespace std; const int Max=128; template<class T>class Stack{public:Stack(){top=-1;}void Push(T x); //入栈T Pop(); //进栈T GetTop(); //取栈顶元素int isEmpty(); //判断栈是否为空private:int top;T data[Max];};template<class T>void Stack<T>::Push(T x){if(top>=Max-1) throw "上溢";top ++;data[top]=x;}template<class T>T Stack<T>::Pop(){if(isEmpty()) throw "下溢";top--;return data[top+1];}template<class T>T Stack<T>::GetTop(){if(isEmpty())throw "下溢";return data[top];}template<class T>int Stack<T>::isEmpty(){if(top==-1)return 1;elsereturn 0;}int IsOpr(char c); //判断输入字符是否为运算符char Precede(char s,char c); //判断字符的优先级int Operate(int x,char opr,int y); //计算int IsOpr(char c) //判断输入字符是否为运算符{if (c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='#') return 1;elsereturn 0;}char Precede(char s,char c) //判断字符的优先级{switch(s){case '+':case '-':{if(c=='+'||c=='-')return '>';else if (c=='*'||c=='/')return '<';else if(c=='(')return '<';else if(c==')')return '>';elsereturn '>';}break;case '*':case '/':{if(c=='+'||c=='-')return '>';else if (c=='*'||c=='/')return '>';else if(c=='(')return '<';else if(c==')')return '>';elsereturn '>';}break;case '(':{if(c==')')return '=';elsereturn '<';}break;case ')':{return '>';}break;case '#':{if(c=='#')return '=';elsereturn '<';}break;}}int Operate(int x,char opr,int y) //计算{int result;switch (opr){case '+':result = x + y;break;case '-':result = x - y;break;case '*':result = x * y;break;case '/':result = x / y;break;}return result;}void main(){Stack<int> s1; //运算数栈Stack<char> s2; //运算符栈s2.Push('#');int a,b,result,i,n,j=0;char theta;string s;cout<<"请输入算式,出入#号结束"<<endl;cin>>s;while(s[j]!='\0'){if(!IsOpr(s[j])) //是运算数的情况{i=s[j]-'0'; //将字符型转为整型j++;while(!IsOpr(s[j])) //使得可以输入几位数{n=s[j]-'0';i=i*10+n;j++;}s1.Push(i);}else{switch(Precede(s2.GetTop(),s[j])) //比较栈顶运算符和刚输入运算符的优先级{case '<':s2.Push(s[j]);j++;break;case '=':北京邮电大学信息与通信工程学院theta=s2.Pop();j++;break;case '>':theta=s2.Pop();b=s1.Pop();a=s1.Pop();result=Operate(a,theta,b);s1.Push(result);break;}}}cout<<s1.GetTop()<<endl;}4. 总结这次的实验选了题目四,用栈做计算器,在写之前一直觉得这是一个很简单的实验,主要是在网上看到栈做计算器的想,所以觉得应该没什么难度,但是真正做起来才发现难上加难。

实验04 栈的应用---算术表达式的计算

实验04  栈的应用---算术表达式的计算

浙江大学城市学院实验报告课程名称数据结构与算法实验项目名称实验四栈的应用---算术表达式的计算学生姓名专业班级学号实验成绩指导老师(签名)日期一.实验目的和要求1.进一步掌握栈的基本操作的实现。

2.掌握栈在算术表达式的计算方面的应用。

二. 实验内容1.编写程序对后缀表达式进行求值(利用栈),即输入任一个后缀表达式,输出该后缀表达式的值。

要求:把栈的基本操作的实现函数存放在文件stack.h 中,在主程序文件test4.cpp中包含后缀表达式求值函数double Compute(char *str)与主函数。

主函数可以参考如下:void main(){char str[50];printf("请输入一个后缀表达式:");gets(str);printf("后缀表达式值为:%f\n", Compute(str) );}2.填写实验报告,实验报告文件取名为report4.doc。

3.上传实验报告文件report4.doc与源程序文件stack.h及test4.cpp到Ftp服务器上你自己的文件夹下。

三. 函数的功能说明及算法思路包括每个函数的功能说明,及一些重要函数的算法实现思路void Change( char *S1, char *S2 ):中缀表达式转化为后缀表达式double Compute(char *str)::后缀表达式求值void InitStack (Stack &S):初始化栈Int EmptyStack (Stack S):判断栈是否为空void Push(Stack &S, ElemType item):入栈ElemType Pop(Stack &S):出栈ElemType Peek(Stack S):取栈顶元素void ClearStack (Stack &S):清除栈四. 实验结果与分析包括运行结果截图等五. 心得体会记录实验感受、上机过程中遇到的困难及解决办法、遗留的问题、意见和建议等。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

浙江大学城市学院实验报告
课程名称数据结构与算法
实验项目名称实验四栈的应用---算术表达式的计算
学生姓名专业班级学号
实验成绩指导老师(签名)日期
一.实验目的和要求
1.进一步掌握栈的基本操作的实现。

2.掌握栈在算术表达式的计算方面的应用。

二. 实验内容
1.编写程序对后缀表达式进行求值(利用栈),即从键盘输入任一个后缀表达式,输出该后缀表达式的值。

要求:把栈的基本操作的实现函数存放在文件stack.h中,在主程序文件test4.cpp中包含后缀表达式求值函数double Compute(char *str)与主函数。

2.填写实验报告,实验报告文件取名为report4.doc。

3.上传实验报告文件report4.doc与源程序文件stack.h及test4.cpp到Ftp服务器上你自己的文件夹下。

三. 函数的功能说明及算法思路
包括每个函数的功能说明,及一些重要函数的算法实现思路
四. 实验结果与分析
包括运行结果截图等
五. 心得体会
记录实验感受、上机过程中遇到的困难及解决办法、遗留的问题、意见和建议等。

看着书写,问题不大。

自己写可能会漏写一些情况。

【附录----源程序】
Test4.cpp
#include<iostream.h>
#include<stdlib.h>
#include"stack.h"
double Compute(char *str){
Stack S;
InitStack(S);
double x,y;
int i = 0;
while(str[i]){
if(str[i] == ' '){
i++;
continue;
}
switch(str[i]){
case'+':
x = Pop(S) + Pop(S);
i++;
break;
case'-':
x = Pop(S);
x = Pop(S) - x;
i++;
break;
case'*':
x = Pop(S) * Pop(S);
i++;
break;
case'/':
x = Pop(S);
if(x != 0.0)
x = Pop(S)/x;
else{
cerr<<"Divide by 0!"<<endl;
exit(1);
}
i++;
break;
default:
x = 0;
while(str[i] >= 48 && str[i] <= 57){
x = x*10+str[i]-48;
i++;
}
if(str[i] == '.'){
i++;
y = 0;
double j = 10.0;
while(str[i] >= 48 && str[i] <= 57){
y = y + (str[i] - 48)/j;
i++;
j*=10;
}
x += y;
}
}
Push(S,x);
}
if(EmptyStack(S)){
cerr<<"Stack is empty"<<endl;
exit(1);
}
x = Pop(S);
if(EmptyStack(S))
return x;
else{
cerr<<"expression error!"<<endl;
exit(1);
}
ClearStack(S);
}
void main(){
char str[80];
cout<<"请输入算数表达式:";
cin.getline(str,sizeof(str));
cout<<"值为:"<<Compute(str)<<endl;
}
Stack.h
#define ElemType double
struct Stack{
ElemType *stack;
int top;
int Maxsize;
};
void InitStack(Stack& S){
S.Maxsize = 10;
S.stack = new ElemType[S.Maxsize];
if(!S.stack){
cerr<<"动态存储分配失败"<<endl;
exit(1);
}
S.top = -1;
}
void Push(Stack& S,ElemType item){
if(S.top == S.Maxsize-1){
int k = sizeof(ElemType);
S.stack = (ElemType*)realloc(S.stack,2*S.Maxsize*k);
S.Maxsize = 2*S.Maxsize;
}
S.top++;
S.stack[S.top] = item;
}
ElemType Pop(Stack& S){
if(S.top == -1){
cerr<<"Stack is empty!"<<endl;
exit(1);
}
S.top--;
return S.stack[S.top+1];
}
ElemType Peek(Stack& S){
if(S.top == -1){
cerr<<"Stack is empty!"<<endl;
exit(1);
}
return S.stack[S.top];
}
bool EmptyStack(Stack& S){
return S.top == -1;
}
void ClearStack(Stack& S){
if(S.stack){
delete []S.stack;
S.stack = 0;
}
S.top = -1;
S.Maxsize = 0;
}。

相关文档
最新文档