后缀表达式转化为前缀表达式并求值

合集下载

第二章 前缀表达式、中缀表达式、后缀表达式的转换

第二章 前缀表达式、中缀表达式、后缀表达式的转换

Stack
* ( +
a b c
Outpu t
* + d e
a+b*c+(d*e+f)*g
11. 读到“+”,弹出“*”并输出,然后将“+”压入栈中。 12.读到f,直接输出。 此时栈和输出的情况如下:
Stack
* ( +
a b c * +d e * f
Outpu t
a+b*c+(d*e+f)*g
Stack
++ a * b c * + * d e f g
Outpu t
任务二:将下列中缀表达式转换为前缀表达式
中缀表达式 前表达式
• 1+((2+3)*4)-5 • a-(b + c/d)*e • a + b*(c + d/e) • a*(b + c)-d
•? •? •? •?
思考
中缀表达式到前缀表达式、 后缀表达式是否还有其他的转换 方法?
Stack
* +
a b c
Outpu t
a+b*c+(d*e+f)*g
6.读到“+”,因为栈顶元素“*”优先级比“+”高,所以弹出“*” 并输出,同理,栈中下一个元素“+”优先级与读到的操作符“+”一样, 所以也要弹出并输出。然后再将读到的“+”压入栈中。
此时栈和输出的情况如下:
Stack
+
a b c
前缀表达式的计算机求值举例
前缀表达式“-*+3456” (1)从右至左扫描,将6、5、4、3压入堆栈; (2)遇到+运算符,因此弹出3和4(3为栈顶元素、4为次顶元素), 计算出3+4的值,得7,再将7入栈;

后缀表达式转前缀表达式的规则

后缀表达式转前缀表达式的规则

后缀表达式转前缀表达式的规则后缀表达式(也称为逆波兰表达式)是一种不需要括号的表达式表示方式,通过在操作符号后面输入操作数来表示操作的顺序。

前缀表达式(也称为波兰表达式)则是将操作符号放在操作数前表示操作顺序。

在实际计算中,后缀表达式更为常用,因为它可以通过栈的方式快速计算,而前缀表达式需要反向扫描以计算数值。

然而,在一些情况下,需要将后缀表达式转换成前缀表达式,以下是该过程的规则。

规则1:倒序读取后缀表达式要将后缀表达式转换成前缀表达式,需要先倒序读取后缀表达式(也就是从右向左读取)。

例如,对于后缀表达式“3 5 + 2 *”,倒序读取为“* 2 + 5 3”。

规则2:将操作数压入栈中在倒序读取后缀表达式时,遇到操作数(也就是数字)就将其压入栈中。

例如,在“* 2 + 5 3”中,遇到“2”、“5”、“3”时,将其压入栈中。

规则3:遇到操作符时,出栈两个操作数当遇到操作符时,需要从栈中出栈两个操作数进行计算,并将结果压入栈中。

例如,在“* 2 + 5 3”中,遇到“+”时,需要出栈操作数“5”和“3”进行加法计算,并将结果“8”压入栈中。

规则4:生成前缀表达式在倒序读取后缀表达式并执行相应操作后,最终得到了一个栈,栈顶元素即为前缀表达式的起始点。

例如,在执行“* 2 + 5 3”的转换后,得到的栈中只有一个元素“* + 5 3 2”,即为转换后的前缀表达式。

举例来说,考虑转换后缀表达式“2 3 * 4 +”。

按照上述规则进行转换:1. 倒序读取:+ 4 * 3 22. 操作数入栈:[4]3. 操作数入栈:[4, 2]4. 乘法计算:[6]5. 加法计算:[10]6. 得到的前缀表达式为“+ * 3 2 4”。

需要注意的是,当表达式中存在多个操作数时,需要在操作数之间添加空格,以便在倒序读取后可以正确地将操作数区分开。

总结后缀表达式转前缀表达式可以通过将后缀表达式反向读取,同时使用栈的方式进行计算,最终得到前缀表达式。

“中序表达式”转换为“前序表达式”、“后序表达式”

“中序表达式”转换为“前序表达式”、“后序表达式”

“中序表达式”转换为“前序表达式”、“后序表达式” 上周末参照书本写了个“计算器”的程序,其中最令我费解的就是“前序表达式”、“后续表达式”,好像记得⽼师在上课的时候讲过,估计当时也没听懂,看的稀⾥糊涂的,不过现在⼤概明⽩了…… 在此仅做以笔记。

⾸先看下⾯所⽰表格:中序表达式2*3/(2-1)+3*(4-1)前序表达式+/*23-21*3-41后序表达式23*21-/341-*+ 中序表达式对我们⽽⾔是很直观的(我们平时接触的就是这个),但计算机处理起来⽐较⿇烦(括号、优先级之类的),前序和后序表达式中没有括号,⽽且在计算中只需单向扫描,不需要考虑运算符的优先级。

以前序表达式“+/*23-21*3-41”为例,从右往左,先取出两个操作数“1”、“4”和⼀个运算符“-”,计算“4-1”,将结果3回填到字符串中,现在字符串变为“+/*23-21*33”。

再从右⾄左取两个数“3”、“3”和“*”,计算“3*3”,将结果“9”回填到字符串,得“+/*23-219’”, 再取数,连续取出“9”、“1”、“2”,直到取出⼀个运算符“-”,将与运算符最近的两个操作数进⾏计算,即“2-1”得“1”,回填字符串中,现在为“+/*239” 重复上述步骤,取出“2*3”=6,回填字符串得到“+/619”, 再取“6/1”=6,得到“+69”, 再取“6+9”=15。

运算完毕。

即从右⾄左取数,直到取出⼀个运算符,将刚取出的紧挨着运算符的两个操作数按运算符进⾏计算,结果回填⾄运算符。

重复该步骤,直到最后只剩下⼀个字符串则剩下的字符串即为结果。

后序表达式的字符串扫描⽅式正好和前序相反,是从左往右扫描,规则类似。

中序表达式转前序表达式步骤1、反转输⼊字符串,如“2*3/(2-1)+3*(4-1)” 反转后为“ )1-4(*3+)1-2(/3*2”,2、从字符串中取出下⼀个字符 2.1.如果是操作数,则直接输出 2.2.如果是“)”,压⼊栈中 2.3.如果是运算符但不是“(”,“)”,则不断循环进⾏以下处理 2.3.1.如果栈为空,则此运算符进栈,结束此步骤 2.3.2.如果栈顶是“)”,则此运算符进栈,结束此步骤 2.3.2.如果此运算符与栈顶优先级相同或者更⾼,此运算符进栈,结束此步骤 2.3.4.否则,运算符连续出栈,直到满⾜上述三个条件之⼀,然后此运算符进栈 2.4、如果是“(”,则运算符连续出栈,直到遇见“)”为⽌,将“)”出栈且丢弃之3、如果还有更多的字符串,则转到第2步4、不在有未处理的字符串了,输出栈中剩余元素5、再次反转字符串得到最终结果 我第⼀次看到这个的时候就没看懂是什么意思,在⽹上查了点,⼜瞪了它好久才明⽩了,就以“2*3/(2-1)+3*(4-1),”为例做以下说明: 2*3/(2-1)+3*(4-1),反转得“ )1-4(*3+)1-2(/3*2 ”; 取第⼀个字符串为“)”,⼊栈(此时栈中为“)”); 取下⼀个“1”,是操作数,直接输出(⽬前输出“1”); 取下⼀个“-”,既不是“)”,也不是“(”,则转到2.3,此时栈顶为“)”,则该运算符进栈(栈中为“-、)”); 取下⼀个“4”,直接输出(⽬前输出的是“14”); 取下⼀个“(”,运算符连续出栈(栈中此时为“-、)”),直到遇见“)”,此时输出“-”(⽬前输出“14-”,栈为空); 取下⼀个“*”,既不是“)”,也不是“(”,则转到2.3,进栈(栈为空); 取下⼀个“3”,直接输出(⽬前输出“14-3”); 取下⼀个“+”,此时栈顶为“*”,“+”的优先级⽐“*”低(2.3.4),则运算符连续出栈(只有⼀个*出栈,此时栈为空符合2.3.1,继续下⼀步),“+”进栈; 取下⼀个“)”,进栈(此时栈中为“)、+”); 取下⼀个“1”直接输出(⽬前输出为14-3*1); 取下⼀个“-”,此时栈顶为“)”,“-”进栈(栈中此时为“-、)、+”); 取下⼀个“2”,直接输出(⽬前输出“14-3*12”); 取下⼀个“(”,运算符连续出栈,直到遇见“)”,此时栈中为“-、)、+”,输出-,且抛弃“)”,此时输出为“14-3*12-”,栈中为“+”; 取下⼀个“/”,优先级⽐栈顶“+”⾼,此运算符进栈; 取下⼀个“3”,直接输出(此时输出“14-3*12-3”); 取下⼀个“*”,优先级⽐栈顶“+”⾼,此运算符进栈; 取下⼀个“2”,输出(此时输出“14-3*12-32”); 不在有未处理的运算符,输出栈中剩余元素,结果的“14-3*12-32*/+”; 反转字符串的“+/*23-21*3-41”。

中缀表达式转换为前缀表达式

中缀表达式转换为前缀表达式

中缀表达式转换为前缀表达式中缀表达式转换为前缀表达式在《》中,我们讨论了对前缀表达式如何计算:设置⼀个操作数栈,对前缀表达式从右到左扫描,遇到操作数直接⼊栈,遇到操作符则从操作数栈弹栈,先弹left值后弹right值,根据操作符进⾏相应的计算,并将计算结果压⼊到操作数栈中,最终将整个前缀表达式扫⾯完毕。

这时操作数栈中只有⼀个元素,该元素的值即为前缀表达式的值。

在《》中,我们讨论了如何将⼀个中缀表达式转换为其对应的后缀表达式。

其思想为:设置⼀个操作符栈,如果遇到操作数,则直接将操作数放进后缀表达式中,如果遇到⾮操作数,则:如果是左括号,则将左括号⼊栈;如果是右括号,则从操作符栈中将操作符弹栈,放⼊后缀表达式中,直⾄栈空或遇到栈中的左括号,并将左括号弹栈;如果是其他操作符,则⽐较其优先级与栈中操作符优先级情况,如果栈中的操作符的优先级⼤于等于当前操作符,则将栈中操作符弹栈,直⾄栈空,或栈中操作符优先级⼩于当前操作符的优先级,将当前操作符压栈。

当从左到右顺序扫描完整个中缀表达式后,检测操作符栈,如果⾮空,则依次弹栈,将弹出的操作符依次压⼊到后缀表达式中。

最终,得到中缀表达式对应的后缀表达式。

如果还想计算后缀表达式的值,则可以参考《》。

本⽂我们是讨论如何将中缀表达式转换为前缀表达式。

我们先给出中缀表达式转换前缀表达式的程序,然后再对程序进⾏相关讲解,之后在与中缀表达式转换后缀表达式的过程进⾏⽐较,分析其中的差异存在于哪⾥。

// 中缀表达式转换为前缀表达式#include <iostream>#include <vector>#include <string>#include <sstream>#include <map>#include <stack>#include <algorithm>using namespace std;void GetInfix(vector<string>& infix){infix.clear();string line;getline(cin, line);istringstream sin(line);string tmp;while (sin >> tmp){infix.push_back(tmp);}}// 初始化操作符void InitOperators(map<string, int>& opers){opers.clear();opers["("] = 100;opers[")"] = 900;opers["+"] = 100;opers["-"] = 100;opers["*"] = 200;opers["/"] = 200;}bool IsOperator(const string& op, const map<string, int>& opers){auto cit = opers.find(op);if (cit != opers.end()){return true;}else{return false;}}void InfixToPrefix(const vector<string>& infix, vector<string>& prefix, map<string, int>& opers){prefix.clear();stack<string> stk; // 操作符栈for (int i = infix.size() - 1; i >= 0; --i) // 从右到左扫描{if (!IsOperator(infix[i], opers)) // 如果是操作数{prefix.push_back(infix[i]);}else// 如果是操作符{if (infix[i] == ")") // 如果是右括号,则直接⼊栈{stk.push(infix[i]);}else if (infix[i] == "(") // 如果是左括号{// 依次弹出栈中的操作符,直⾄遇到右括号while (!stk.empty()){if (stk.top() == ")"){stk.pop();break;}else{prefix.push_back(stk.top());stk.pop();}}}else// 如果是其他操作符{while (!stk.empty() && stk.top() != ")" && opers[stk.top()] > opers[infix[i]]) // 栈顶操作符优先级⼤于当前操作符优先级{prefix.push_back(stk.top());stk.pop();}// 将当前操作符⼊栈stk.push(infix[i]);}}}// 检测操作符栈是否为空while (!stk.empty()){prefix.push_back(stk.top());stk.pop();}// 将prefix翻转reverse(prefix.begin(), prefix.end());return;}void Display(const vector<string>& fix){for (auto i = 0; i != fix.size(); ++i){cout << fix[i] << '';}cout << endl;}int main(){map<string, int> opers;InitOperators(opers);while (true){vector<string> infix, prefix;GetInfix(infix);Display(infix);InfixToPrefix(infix, prefix, opers);Display(prefix);cout << endl;}return0;}⾸先说明的是,我们的中缀表达式输⼊是⽤空⽩符间隔的,⽽没有对中缀表达式进⾏词法分析,对中缀表达式的词法分析可以参考《》。

C#算术表达式求值(后缀法),看这一篇就够了

C#算术表达式求值(后缀法),看这一篇就够了

C#算术表达式求值(后缀法),看这⼀篇就够了⼀、种类介绍算术表达式有三种:前缀表达式、中缀表达式和后缀表达式。

⼀般⽤的是中缀,⽐如1+1,前后缀就是把操作符移到前⾯和后⾯,下⾯简单介绍⼀下这三种表达式。

1、前缀表⽰法前缀表⽰法⼜叫波兰表⽰法,他的操作符置于操作数的前⾯(例:+ 1 2),是波兰数学家扬·武卡谢维奇1920年代引⼊的,⽤于简化命题逻辑。

因为我们⼀般认为操作符是在操作数中间的,所以在⽇常⽣活中⽤的不多,但在计算机科学领域占有⼀席之地。

⼀般的表⽰法对计算机来说处理很⿇烦,每个符号都要考虑优先级,还有括号这种会打乱优先级的存在,将使计算机花费⼤量的资源进⾏解析。

⽽前缀表⽰法没有优先级的概念,他是按顺序处理的。

举个例⼦:9-2*3这个式⼦,计算机需要先分析优先级,先乘后减,找到2*3,再进⾏减操作;化成前缀表⽰法就是:- 9 * 2 3,计算机可以依次读取,操作符作⽤于后⼀个操作数,遇到减就是让9减去后⾯的数,⽽跟着9的是乘,也就是说让9减去乘的结果,这对计算机来说很简单,按顺序来就⾏了。

2、中缀表⽰法这也就是我们⼀般的表⽰法,他的操作符置于操作数的中间(例:1 + 2),前⾯也说过这种⽅法不容易被计算机解析,但他符合⼈们的普遍⽤法,许多编程语⾔也就⽤这种⽅法了。

在中缀表⽰法中括号是必须有的,要不然运算顺序会乱掉。

3、后缀表⽰法后缀表⽰法⼜叫逆波兰表⽰法,他的操作符置于操作数的后⾯(例:1 2 +),他和前缀表⽰法都对计算机⽐较友好,但他很容易⽤堆栈解析,所以在计算机中⽤的很多。

他的解释过程⼀般是:操作数⼊栈;遇到操作符时,操作数出栈,求值,将结果⼊栈;当⼀遍后,栈顶就是表达式的值。

因此逆波兰表达式的求值使⽤堆栈结构很容易实现,且能很快求值。

注意:逆波兰记法并不是简单的波兰表达式的反转。

因为对于不满⾜交换律的操作符,它的操作数写法仍然是常规顺序,如,波兰记法/ 6 3的逆波兰记法是6 3 /⽽不是3 6 /;数字的数位写法也是常规顺序。

前缀、中缀、后缀表达式的相互转换方法

前缀、中缀、后缀表达式的相互转换方法

前缀、中缀、后缀表达式的相互转换⽅法前缀式、中缀式、后缀式相互转换⼀. 中缀式转化成前缀式和后缀式:⼀个中缀式到其他式⼦的转换⽅法这⾥我给出⼀个中缀表达式a +b *c - (d +e )第⼀步:按照运算符的优先级对所有的运算单位加括号式⼦变成:( ( a + ( b * c ) ) - ( d + e ) )第⼆步:转换前缀与后缀表达式中缀转前缀:把运算符号移动到对应的括号前⾯则变成:- ( + ( a * ( b c ) ) + ( d e ) )把括号去掉:- + a * b c + d e 前缀式⼦出现中缀转后缀:把运算符号移动到对应的括号后⾯则变成:( ( a ( b c ) * ) + ( d e ) + ) -把括号去掉:a b c * + d e + - 后缀式⼦出现⼆. 前缀式转化成中缀式:+ a * b c + d e从后往前遇到运算符,将其与后⾯两个运算数结合,加上括号,当成新的运算数(例如:* b c 加上括号,变成 ( * b c )⼀个整体,作为运算数)变成:( - ( + a ( * b c ) ) ( + d e ) )将运算符加在括号内运算数中间。

变成:( ( a + ( b * c ) ) - ( d + e ) )去掉部分括号:a + b * c - ( d + e )(最后去掉的是不影响运算式含义的多余括号)三. 后缀式转化成中缀式:a b c * + d e + -从前往后遇到运算符,将其与前⾯两个运算数结合,加上括号,当成新的运算数变成:( ( a ( b c * ) + ) ( d e + ) - )将运算符加在括号内运算数中间。

变成:( ( a + ( b * c ) ) - ( d + e ) )去掉部分括号:a + b * c - ( d + e )(最后去掉的是不影响运算式含义的多余括号)。

前中后缀表达式的转化例题

前中后缀表达式的转化例题

前中后缀表达式的转化例题【最新版】目录1.前中后缀表达式的转化例题介绍2.前缀表达式的定义和性质3.中缀表达式的定义和性质4.后缀表达式的定义和性质5.表达式转换的方法和步骤6.表达式转换的实际应用案例正文一、前中后缀表达式的转化例题介绍前缀表达式、中缀表达式和后缀表达式是计算机科学中常见的三种表达式表示方法。

它们分别对应着不同的语法结构,具有各自的特点和应用场景。

在实际问题中,有时需要将一种表达式转换为另一种表达式,以便进行相应的操作和分析。

下面我们将通过一个具体的例题来介绍表达式转换的方法。

例题:将中缀表达式 "a + b" 转换为后缀表达式。

二、前缀表达式的定义和性质前缀表达式是一种特殊的二叉树,它的每个内部节点都有一个前缀,即该节点的左子树或右子树的一个路径。

前缀表达式的性质如下:1.前缀表达式只有一个根节点;2.每个节点只有一个前缀;3.前缀表达式的每个叶子节点对应一个变量;4.前缀表达式的每个节点对应一个运算符。

三、中缀表达式的定义和性质中缀表达式是另一种特殊的二叉树,它的每个内部节点都有一个中缀,即该节点的左子树、右子树或该节点本身。

中缀表达式的性质如下:1.中缀表达式只有一个根节点;2.每个节点可以有一个或多个中缀;3.中缀表达式的每个叶子节点对应一个变量;4.中缀表达式的每个节点对应一个运算符。

四、后缀表达式的定义和性质后缀表达式是一种特殊的二叉树,它的每个内部节点都有一个后缀,即该节点的左子树、右子树或该节点本身。

后缀表达式的性质如下:1.后缀表达式只有一个根节点;2.每个节点可以有一个或多个后缀;3.后缀表达式的每个叶子节点对应一个常数或变量;4.后缀表达式的每个节点对应一个运算符。

五、表达式转换的方法和步骤1.首先,根据中缀表达式构建一棵二叉树;2.遍历二叉树,将每个节点转换为对应的前缀表达式或后缀表达式;3.对于前缀表达式,遍历二叉树的每个节点,将该节点的左子树或右子树转换为前缀表达式,并将该节点对应的运算符添加到前缀表达式中;4.对于后缀表达式,遍历二叉树的每个节点,将该节点的左子树或右子树转换为后缀表达式,并将该节点对应的运算符添加到后缀表达式中;5.最后,将所有的前缀表达式或后缀表达式按照一定的顺序连接起来,得到最终的表达式。

C语言实现中缀、后缀、前缀表达式 相互转化并求值

C语言实现中缀、后缀、前缀表达式 相互转化并求值

C语言实现中缀、后缀、前缀表达式相互转化并求值1.问题描述(1)表达式求值问题表达式是数据运算的基本形式。

人们的书写习惯是中缀式,如:11+22*(7-4)/3。

中缀式的计算按运算符的优先级及括号优先的原则,相同级别从左到右进行计算。

表达式还有后缀式(如:22 7 4 - * 3 / 11 +)和前缀式(如:+ 11 / * 22 –7 4 3)。

后缀表达式和前缀表达式中没有括号,给计算带来方便。

如后缀式计算时按运算符出现的先后进行计算。

本设计的主要任务是进行表达式形式的转换及不同形式的表达式计算。

2.数据结构设计(1)表达式求值问题由于表达式中有字符与数字两种类型,故定义结点一个标志域data,标志结点存储的为字符data=2还是数字data=1,再寻找结点中对应的存储位置,读取数字域data1,字符域data2。

而在前缀表达式时,存在表达式逆序,因表达式类型不统一,用栈逆序极不方便,选择构建双向链表,存储表达式。

typedef struct Node //定义存储中缀表达式的结点类型{int data;int data1;char data2;struct Node *next;}Lnode;typedef struct Node2 //定义存储前缀表达式的结点类型{int data;int data1;char data2;struct Node2 *next;struct Node2 *prior;}Lnode2;3.运行、测试与分析(1)表达式求值问题(1)按提示输入中缀表达式,如图1.1所示。

如输入中缀表达式不正确,提示输入有误,如图1.2,1.3所示。

图1.1图1.2图1.3(2)选择表达式转换并求值方式。

按“1”选择中缀表达式求值,如图1.4所示。

图1.4(3)按“2”选择中缀表达式转变为后缀表达式并求值,如图1.5所示。

图1.5(4)按“3”选择中缀表达式转变为前缀表达式并求值,如图1.6所示。

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

#include <stdio.h>#include <stdlib.h>#include <string.h>#define STACK_INIT_SIZE 100#define STACKINCREMENT 10#define OK 1#define OVERFLOW -2#define ERROR 0#define TRUE 1#define FALSE 0typedef int Selemtype;typedef int Status;#define MAX 50char string1[MAX]; //定义两个字符串分别存放中缀表达式和后缀表达式char string2[MAX];int result;typedef struct{Selemtype *base; //在构造之前和销毁之后,base的值为NULLSelemtype *top; //栈顶指针int stacksize; //当前分配的存储空间,以元素为单位}SqStack;Status InitStack(SqStack *S);Status Push(SqStack *S,Selemtype e);Status Pop(SqStack *S,Selemtype e);Status InitStack(SqStack *S){ //构造一个空栈SS->base=(Selemtype*)malloc(STACK_INIT_SIZE*sizeof(Selemtype));if(!S->base) return OVERFLOW; //存储分配失败S->top=S->base;S->stacksize=STACK_INIT_SIZE;return OK;}Status Push(SqStack *S,Selemtype e){ //插入元素e为新的栈顶元素if(S->top-S->base>=S->stacksize){ //栈满,追加存储空间S->base=(Selemtype*)realloc(S->base,(S->stacksize+STACKINCREMENT)*sizeof(Selemtype));if(!S->base) return OVERFLOW; //存储分配失败S->top=S->base+S->stacksize;S->stacksize+=STACKINCREMENT;}*S->top++=e;return OK;}Status Pop(SqStack *S,Selemtype e){ //若栈不空值,则删除S的栈顶元素,用e返回其值,并返回OK,否则返回ERRORif(S->top==S->base) return ERROR;e=*--S->top;return OK;}Status StackEmpty(SqStack *S){ //若栈S为空,则返回TRUE,否则返回FALSEif(S->top==S->base)return TRUE;elsereturn FALSE;}Selemtype GetTop(SqStack *S){ //取栈顶元素并用e返回其值Selemtype e;if(S->top==S->base) return ERROR;e=*(S->top-1);return e;}void transform(char str1[],char str2[]){ //将中缀表达式转换为后缀表达式SqStack Op;InitStack(&Op); //定义一个空栈用来存放运算符Push(&Op,'#');Selemtype top; //取得运算符栈的栈顶元素赋值给topSelemtype e=NULL; //出栈的栈顶元素赋值给eint i=0,j=0,m;char a;m=strlen(str1);for(i=0;i<m;i++){a=str1[i];if('0'<=str1[i]&&str1[i]<='9') //如果是操作数直接放在后缀表达式中{str2[j]=str1[i];j++;}else{str2[j]=' ';j++;switch(a){case '(':{Push(&Op,a);} break;case '*':case '/':top=GetTop(&Op);if((top=='*')||(top=='/')){Pop(&Op,e);str2[j]=top;j++; //比其高,现将栈顶运算符出栈,再进栈。

Push(&Op,a);}else{Push(&Op,a);} break;case '+':case '-':top=GetTop(&Op);if(top=='+'||top=='-'||top=='*'||top=='/'){Pop(&Op,e);str2[j]=top;j++;Push(&Op,a);}else{Push(&Op,a);} break;case ')':{top=GetTop(&Op);Pop(&Op,e);while(top!='('){str2[j]=top;j++;top=GetTop(&Op);Pop(&Op,e);}} break;}}}top=GetTop(&Op);Pop(&Op,e);while(top!='#'){str2[j]=top;j++;top=GetTop(&Op);Pop(&Op,e);}str2[j]=top;printf("转化后的后缀表达式为:%s\n",str2);}Selemtype counttem(char str[]){ //计算后缀表达式的值SqStack S;InitStack(&S);int len;len=strlen(str);Selemtype A[10];int m,n,p,e=NULL,k,E;int i,j,l,ch,zh; //zh为字符型转化为的整形数for(i=0;i<len;i++){if('0'<str[i]&&str[i]<='9'){k=i;j=0;while('0'<=str[k]&&str[k]<='9') //将字符型的一串数字转化为整形{A[j]=str[k]-48;j++;k++;}ch=A[j-1];E=1;for(l=1;l<j;l++){E=10*E;zh=A[j-l-1]*E;ch+=zh;}Push(&S,ch);i=k-1;}else if(str[i]=='+'||str[i]=='-'||str[i]=='*'||str[i]=='/'){m=GetTop(&S);Pop(&S,e);n=GetTop(&S);Pop(&S,e);switch (str[i]){case'+':p=m+n; break;case'-':p=n-m; break;case'*':p=n*m; break;case'/':p=n/m; break;}Push(&S,p);}else if(str[i]==' '){}else if(str[i]=='#'){result=GetTop(&S);}}printf("表达式的运算结果为:%d\n",result);return result;}void main(){printf("请输入表达式(整数的四则运算)");gets(string1); //用字符串string1盛放中缀表达式transform(string1,string2); //用字符串string2盛放后缀表达式counttem(string2);}。

相关文档
最新文档