大数据结构中缀表达式转后缀表达式
将中缀表达式转换成后缀表达式的三种方法
将中缀表达式转换成后缀表达式的三种方法中缀表达式是我们平常最常见的表达式形式,但在计算机的运算过程中,我们常常需要将中缀表达式转换成后缀表达式,因为后缀表达式具有易于计算的特点。
那么,接下来我们将介绍三种将中缀表达式转换成后缀表达式的方法。
一、栈的方法这种方法是最常见的一种方法,也是比较易理解的一种方法。
我们可以借助栈来完成中缀表达式转换成后缀表达式的过程。
具体的操作如下:1. 声明一个操作符的栈stack(栈中存放操作符)和一个后缀表达式的列表res(列表中存放转换后的后缀表达式)。
2. 从左到右遍历中缀表达式。
3. 若当前字符为数字,则直接将该数字添加到res中。
4. 若当前字符为左括号“(”,则将其压入stack栈中。
5. 若当前字符为右括号“)”,则依次弹出stack栈中的操作符并加入到res中,直到遇到左括号为止。
6. 若当前字符为操作符,那么则需判断当前操作符与stack栈顶操作符的优先级,若当前操作符的优先级小于等于栈顶操作符,则弹出栈顶操作符并加入到res中,重复此步骤,直到当前操作符大于栈顶操作符优先级,最后将当前操作符压入stack栈。
7. 当遍历完整个中缀表达式后,若stack栈中还有剩余操作符,则依次弹出栈顶操作符并加入到res中。
8. 最终,res中的表达式就是转换后的后缀表达式。
二、递归调用方法这种方法是使用递归的方式来完成。
具体的操作如下:1. 若当前遍历的字符为数字,则直接输出该数字。
2. 若当前遍历的字符为左括号“(”,则递归读取该括号内的表达式。
3. 若当前遍历的字符为右括号“)”,则返回。
4. 若当前遍历的字符为操作符,“x”,“/”,“+”,“-”,则递归调用该表达式右边的操作符,比如“x”,“/”,然后再递归调用左边的操作符,比如“+”,“-”,然后输出左操作数和右操作数,最后输出当前操作符。
5. 最终,输出的表达式即为转换后的后缀表达式。
三、判断法这种方法也是比较常见的一种方法。
数据结构中缀表达式改后缀表达式
程序从标准输入读入一行字符串,是一个合法的后缀表达式,数字和运 算符之间
由空格分隔。数字可以是带小数部分的浮点数。
输出形式: 向标准输出打印结果,输出只有一行,是转换后的中缀表达式。 并且 : 1、各分量(包括括号)紧密输出,不使用空格进行分隔; 2、在转换后的各运算数的出现顺序不变; 3、浮点数保留输入时的小数位数。
Node p,q,f;
//连接两个链表
if(flag==0) {
printf("错误\n"); exit(0); }
E->Lists[flag-1]->c=ch;
p=E->Lists[flag-1]; f=E->Lists[flag]->next;
while(p->next!=NULL) p=p->next;
*/
#include<stdio.h> #include<stdlib.h>
struct Expression; typedef struct Expression *Node;
struct Expressionlist; typedef struct Expressionlist *Elist;
struct Expression {
7. 之后是符号“+”,此时当前栈顶元素比这个“+”的优先级高,因此栈中元素出 栈并输出(没有比“+”号更低的优先级,所以全部出栈),总输出表达式为 9 3 1 - 3 * +.然后将当前这个符号“+”进栈。也就是说,前 6 张图的栈底的“+”是指中缀 表达式中开头的 9 后面那个“+”,而下图中的栈底(也是栈顶)的“+”是指 “9+(3-1)*3+”中的最后一个“+”。 8. 紧接着数字 10,输出,总表达式变为 9 3 1-3 * + 10。
中缀表达式转后缀表达式---栈--二叉树---四则运算
中缀表达式转后缀表达式---栈--⼆叉树---四则运算 我们平常书写的四则运算表达式属于中缀表达式,形式为"9+(3-1)*3+10/2",因为所有的运算符号都在两操作数之间,所以称为中缀表达式。
我们使⽤中缀表达式来计算表达式的值,不过这种形式并不适合计算机求解。
接下来,我们将中缀表达式转化为后缀表达式,所谓的后缀表达式就是操作符位于操作数后⾯的不包含括号的算数表达式,也叫做逆波兰表达式。
1)⾸先介绍⼀种⼈⼯的转化⽅法()。
以"9+(3-1)*3+10/2"为例,按照运算的规则,找出⾸先计算的部分,这部分包含两个操作数和⼀个操作符,将操作符移动到两个操作数右侧,这就完成了第⼀部分的转换,将这部分看作⼀个操作数,按照运算规则,以相同的⽅法转换,转换过程如下:2)还可以利⽤⼆叉树求得后缀表达式,⾸先利⽤中缀表达式构造⼆叉树,数字是叶⼦节点,操作符为根节点。
每次找到“最后计算”的运算符,作为当前根节点,运算符左侧表达式作为左节点,右侧表达式作为右节点,然后递归处理()。
9+(3-1)*3+10/2对应的⼆叉树的构造过程如下图所⽰: 此⼆叉树做后序遍历就得到了后缀表达式。
对应代码:3)还可以利⽤栈来实现中缀表达式转化为后缀表达式。
转化⽅法如下所述:a.从左向右扫描表达式,如果是数字就输出,否则转b。
b.如果当前扫描的字符是")",则栈顶元素出栈并输出⼀直到栈顶元素为"(",然后删除栈顶元素"(",并不输出。
c.如果扫描的字符或者栈顶元素是“(”,扫描的字符直接⼊栈。
即使扫描的字符是")"也不会⼊栈,因为如果是")",会出栈⾄栈顶元素是"("。
d.如果扫描字符是"+"或者"-",则⼀直出栈⾄栈顶元素为"+"或者"-"或者"("。
数据结构之中缀表达式转后缀表达式
return NULL;
}
S->Next = NULL;
MakeEmpty(S);
return S;
}
//清空栈
void MakeEmpty(Stack S)
{
if(S == NULL)
{
printf("Use CreateStack First!");
{
return 3;
}
else
{
fprintf(stderr,"Input char is invalid!\n");
return -1;
}
}
/****************************************************************
*判断一个字符是不是运算符
*如果是合法的运算符+、-、*、/、(、)则返回0,否则返回1
}
else
{
while(!IsEmpty(S))
{
Pop(S);
}
}
}
//进栈
void Push(ElementType X,Stack S)
{
PtrToNode Tmp;
Tmp = malloc(sizeof(struct Node));
if(Tmp != NULL)
{
Tmp->Element = X;
遇到a,直接输出:
遇到+,此时栈为空,入栈:
遇到b,直接输出:
遇到*,优先级大于栈顶符号优先级,入栈:
遇到c,输出:
遇到+,目前站内的*与+优先级都大于或等于它,因此将栈内的*,+依次弹出并且输出,并且将遇到的这个+入栈:
中缀转后缀表达式计算报告
目录一、设计思想 (01)二、算法流程图 (02)三、源代码 (04)四、运行结果 (14)五、遇到的问题及解决 (16)六、心得体会 (16)一、设计思想(1)中缀表达式转后缀表达式并计算创建一个数组存储输入的计算表达式。
另创建一个数组储存将要生成的后缀表达式。
创建一个栈储存操作符。
对已存储的表达式数组扫描。
判断当前节点,如果是操作数或’.’,直接加入后缀表达式中,如果是操作符,则比较前一个操作符与当前操作符的优先级。
如果前一个操作符的优先级较高,则将前一个操作符加入后缀表达式中,否则将操作符压入操作符栈。
如果遇到左括号’(’,直接入栈;如果遇到右括号’)’,则在操作符栈中反向搜索,直到遇到匹配的左括号为止,将中间的操作符依次加到后缀表达式中。
当执行完以上操作,发现栈中仍有剩余操作符,则将操作符依次加到后缀表达式中。
此时中缀表达式已经转换成了后缀表达式。
对后缀表达式进行计算。
如果后缀表达式为大于0小于9的字符,则将它转换成浮点型数据并存入数栈中。
如果遇到操作符,则从数栈中提取两个数,进行相应的运算。
依次进行下去,当没有运算符是,运算结束得到最后的结果。
(2)直接表达式求值创建一个数组存储输入的计算表达式。
创建两个栈,一个字符型的栈,一个双精度型的栈。
分别用来存储字符和数。
对已存储的表达式数组扫描。
判断当前节点,如果是操作数和’.’,将字符型的操作数转换为浮点型的数后存入操作数栈。
如果是操作符则判断操作符的优先级。
如果字符栈中已存储符号的优先级小于要存入的字符的优先级,则直接让字符入操作符栈。
如果字符栈中已存储符号的优先级大于或等于要存入的字符的优先级,则取出操作符栈中的一个字符和操作数栈中的两个数进行计算,然后将结果存入操作数栈中,同上进行下去,直到字符栈中已存储符号的优先级小于要存入的字符的优先级时,将操作符存入操作符栈中。
当遇到左括号’(’,将左括号直接存入操作符栈中。
当遇到右括号’)’,则在操作符栈中反向搜索,并且每搜到一个字符就在操作数栈中取两个数进行相应的计算。
中缀转后缀数据结构
将中缀表达式转换为后缀表达式需要使用栈数据结构。
具体步骤如下:1. 读入中缀表达式,遇到数字时将其输出,遇到左括号时将其压入栈中。
2. 读入运算符,如果该运算符优先级高于栈顶运算符的优先级,则将栈顶元素弹出并输出,直到遇到优先级更高的运算符或遇到右括号为止。
3. 如果该运算符优先级等于栈顶运算符的优先级,则将该运算符压入栈中。
4. 如果该运算符优先级低于栈顶运算符的优先级,则忽略该运算符。
5. 重复上述步骤,直到读完整个中缀表达式。
6. 将栈中的元素依次弹出并输出,即为转换后的后缀表达式。
例如,对于中缀表达式a + b * c + (d * e + f) * g,其转换成后缀表达式的步骤如下:1. 读到a,直接输出。
2. 读到+,将+ 压入栈中。
3. 读到b,直接输出。
4. 读到*,将* 压入栈中。
5. 读到c,直接输出。
6. 读到+,将栈顶的* 弹出并输出,然后将+ 压入栈中。
7. 读到(,将( 压入栈中。
8. 读到d,直接输出。
9. 读到*,将* 压入栈中。
10. 读到e,直接输出。
11. 读到+,将栈顶的* 弹出并输出,然后将+ 压入栈中。
12. 读到f,直接输出。
13. 读到),将栈顶的+ 弹出并输出,直到遇到左括号为止。
此时右括号")" 的优先级最高,所以直接将其弹出并输出。
然后继续弹出并输出左括号"(" 前遇到的运算符和操作数,直到遇到右括号为止。
此时右括号")" 前已经没有运算符和操作数了,所以直接将其弹出并输出。
14. 读到*,将* 压入栈中。
15. 读到g,直接输出。
16. 中缀表达式已经读完,将栈中的元素依次弹出并输出,得到后缀表达式a b * c + d * e + f * g + 。
中缀转后缀并输出运算步骤
中缀转后缀并输出运算步骤从中缀表达式转换为后缀表达式的过程中,需要遵循一定的规则和算法。
下面将具体介绍中缀转后缀的步骤及其运算过程。
一、引言中缀表达式是我们日常生活中最常见的表达式形式,例如:2 + 3 * 4。
但是,对于计算机来说,中缀表达式并不方便进行计算,因此需要将其转换为后缀表达式。
后缀表达式也被称为逆波兰表达式,它的计算规则更加简单明了。
二、中缀转后缀的规则和算法1. 创建一个空的栈,用于存储运算符。
2. 从左到右遍历中缀表达式的每个元素。
3. 如果当前元素是操作数,则直接输出到后缀表达式。
4. 如果当前元素是左括号"(",则将其压入栈中。
5. 如果当前元素是右括号")",则将栈中的运算符依次弹出并输出到后缀表达式,直到遇到左括号为止。
注意:左括号不输出。
6. 如果当前元素是运算符,则判断栈顶运算符的优先级:- 若栈为空,则直接将当前运算符压入栈中。
- 若栈不为空,且当前运算符的优先级小于等于栈顶运算符的优先级,则将栈顶运算符弹出并输出到后缀表达式,直到栈为空或者栈顶运算符的优先级小于当前运算符。
- 将当前运算符压入栈中。
7. 遍历完中缀表达式后,如果栈中还有运算符,则依次弹出并输出到后缀表达式。
三、运算过程示例考虑中缀表达式:"2 + 3 * 4 - (5 + 6) / 7"1. 创建空栈和空后缀表达式。
2. 从左到右遍历中缀表达式的每个元素:- 遇到"2",为操作数,直接输出到后缀表达式。
- 遇到"+",为运算符,将其压入栈中。
- 遇到"3",为操作数,直接输出到后缀表达式。
- 遇到"*",为运算符,将其压入栈中。
- 遇到"4",为操作数,直接输出到后缀表达式。
- 遇到"-",为运算符,栈顶为"*",优先级高于"-",因此将"*"弹出并输出到后缀表达式,然后将"-"压入栈中。
中缀式和后缀式的相互转换
中缀式和后缀式的相互转换中缀式和后缀式是数学表达式的两种常见表示方式。
中缀式是我们常见的表达式形式,例如"3 + 4 * 5",而后缀式是将运算符放在操作数后面表示,例如"3 4 5 * +"。
将中缀式转换为后缀式可以通过使用栈和优先级规则来完成。
具体步骤如下:1. 创建一个空栈和一个空字符串后缀表达式2. 从左到右扫描中缀表达式的每个元素3. 如果遇到操作数,则将其添加到后缀表达式中4. 如果遇到运算符,则将其与栈顶运算符进行比较:- 如果栈为空或栈顶是左括号"(",则将运算符入栈- 如果运算符优先级高于栈顶运算符,则将运算符入栈- 否则,将栈顶运算符弹出并添加到后缀表达式中,直到栈为空或栈顶是左括号为止,然后将当前运算符入栈5. 如果遇到左括号"(",则将其入栈6. 如果遇到右括号")",则将栈顶运算符弹出并添加到后缀表达式中,直到遇到左括号为止,然后将左括号弹出(左括号不添加到后缀表达式中)7. 扫描完整个中缀表达式后,将栈中剩余的运算符依次弹出并添加到后缀表达式中8. 后缀表达式即为转换结果例如,将中缀式"3 + 4 * 5"转换为后缀式的过程如下:中缀表达式: 3 + 4 * 5初始化:栈为空,后缀表达式为空扫描 3:后缀表达式:3扫描 +:栈为空,运算符入栈扫描 4:后缀表达式:3 4扫描 *:栈顶运算符优先级低于当前运算符,运算符入栈扫描 5:后缀表达式:3 4 5扫描完毕,将栈中剩余运算符弹出:后缀表达式:3 4 5 * +因此,中缀式"3 + 4 * 5"转化为后缀式"3 4 5 * +"。
将后缀式转换为中缀式可以通过使用栈和逆序扫描后缀表达式的方式来完成。
具体步骤如下:1. 创建一个空栈2. 从左到右逆序扫描后缀表达式的每个元素3. 如果遇到操作数,则将其入栈4. 如果遇到运算符,则从栈中弹出两个操作数,并将运算符与操作数组合成一个中缀表达式,并将该中缀表达式入栈5. 扫描完整个后缀表达式后,栈顶的中缀表达式即为转换结果例如,将后缀式"3 4 5 * +"转换为中缀式的过程如下:后缀表达式:3 4 5 * +初始化:栈为空从右到左逆序扫描:扫描 +:弹出操作数5和4,组合为中缀表达式"4 + 5",入栈扫描 *:弹出操作数4和中缀表达式"4 + 5",组合为中缀表达式"(4 + 5) * 4",入栈扫描 3:入栈扫描完毕,栈顶的中缀表达式即为转换结果:中缀表达式:"(4 + 5) * 3"因此,后缀式"3 4 5 * +"转化为中缀式"(4 + 5) * 3"。
算法笔记--中缀表达式转后缀表达式后缀表达式计算
算法笔记--中缀表达式转后缀表达式后缀表达式计算中缀表达式转后缀表达式规则中缀表达式a + b*c + (d * e + f) * g,转换成后缀表达式则为a b c * + d e * f + g * +转换过程需要⽤到栈,具体过程如下:1 如果遇到操作数,我们就直接将其输出。
2 如果遇到操作符,则我们将其放⼊到栈中,遇到左括号时我们也将其放⼊栈中。
3 如果遇到⼀个右括号,则将栈元素弹出,将弹出的操作符输出直到遇到左括号为⽌。
注意,左括号只弹出并不输出。
4 如果遇到任何其他的操作符,如+, *, (等,从栈中弹出元素直到遇到发现更低优先级的元素(或者栈为空)为⽌。
弹出完这些元素后,才将遇到的操作符压⼊到栈中。
有⼀点需要注意,只有在遇到 )的情况下我们才弹出( ,其他情况我们都不会弹出( 。
即:若操作符op的优先级⾼于栈顶操作符的优先级,则压⼊操作符栈若操作符op的优先级⼩于等于栈顶操作符的优先级,则将操作栈的操作符不断弹出到后缀表达式中,直到op的优先级⾼于栈顶操作符的优先级5 如果我们读到了输⼊的末尾,则将栈中所有元素依次弹出。
实例a +b *c + (d *e + f) * g1. ⾸先读到a,直接输出。
2. 读到“+”,将其放⼊到栈中。
3. 读到b,直接输出。
此时栈和输出的情况如下:4. 读到“*”,因为栈顶元素"+"优先级⽐" * " 低,所以将" * "直接压⼊栈中。
5. 读到c,直接输出。
此时栈和输出情况如下:6. 读到" + ",因为栈顶元素" * "的优先级⽐它⾼,所以弹出" * "并输出,同理,栈中下⼀个元素" + "优先级与读到的操作符" + "⼀样,所以也要弹出并输出。
然后再将读到的" + "压⼊栈中。
中缀表达式转后缀表达式最难例题
中缀表达式转后缀表达式最难例题以下是一个较复杂的中缀表达式转后缀表达式的示例:中缀表达式:(3+4*2)/(1-5)^2^3后缀表达式:342*+15-23^^/首先,我们可以使用运算符优先级来决定操作符的顺序。
一般来说,乘法和除法的优先级最高,然后是加法和减法,最后是幂运算。
在同一优先级下,操作符从左到右处理。
接下来,我们使用一个栈来辅助转换。
按照从左到右的顺序扫描中缀表达式:1. 如果遇到数字,直接将其添加到后缀表达式中。
2. 如果遇到运算符,首先将栈顶的运算符与当前运算符进行优先级比较:- 如果栈为空,或者栈顶运算符为左括号"(",则将当前运算符直接入栈。
- 如果当前运算符的优先级高于栈顶运算符,则将当前运算符入栈。
- 如果当前运算符的优先级低于或等于栈顶运算符,则将栈顶运算符弹出并添加到后缀表达式中,然后继续比较当前运算符与新的栈顶运算符的优先级,直到当前运算符可以入栈。
3. 如果遇到左括号"(",直接将其入栈。
4. 如果遇到右括号")",则将栈顶运算符弹出并添加到后缀表达式中,直到遇到左括号"("。
注意,左括号"("只弹出并丢弃,不添加到后缀表达式中。
5. 最后,如果中缀表达式扫描完成,但栈中仍有运算符,则依次弹出并添加到后缀表达式中。
根据上述规则,将中缀表达式“(3+4*2)/(1-5)^2^3”转换为后缀表达式的过程如下:中缀表达式: (3+4*2)/(1-5)^2^3后缀表达式:遍历字符"(",将其入栈。
中缀表达式: 3+4*2)/(1-5)^2^3后缀表达式:遍历数字"3",将其添加到后缀表达式中。
中缀表达式: +4*2)/(1-5)^2^3后缀表达式: 3遍历字符"+",将其入栈。
中缀表达式: 4*2)/(1-5)^2^3后缀表达式: 3遍历数字"4",将其添加到后缀表达式中。
数据结构后缀表达式转换过程
数据结构后缀表达式转换过程在计算机科学中,数据结构是非常重要的一部分,而表达式的转换则是其中一个常见且关键的操作。
今天,咱们就来深入探讨一下后缀表达式的转换过程。
先来说说啥是后缀表达式。
简单来讲,后缀表达式就是把运算符放在操作数的后面。
比如说,对于常见的中缀表达式“2 +3”,它的后缀表达式就是“2 3 +”。
那为啥要研究后缀表达式的转换呢?这是因为后缀表达式在计算机计算时更方便、更高效。
那后缀表达式是怎么从常见的中缀表达式转换过来的呢?这就得提到一个重要的工具——栈。
咱们来一步步看这个转换过程。
假设咱们有一个中缀表达式,比如“3 +4 2 1”。
第一步,咱们要把这个中缀表达式中的数字和运算符一个一个地读进来。
当读到数字的时候,直接输出。
比如说,一开始读到 3,那就直接把 3 输出。
当读到运算符的时候,这就得和栈打交道了。
如果栈为空,那就把这个运算符直接入栈。
要是栈不为空,那就得比较当前运算符和栈顶运算符的优先级。
如果当前运算符的优先级高于栈顶运算符,那就把当前运算符入栈;要是当前运算符的优先级低于或者等于栈顶运算符,那就把栈顶运算符出栈并输出,然后再继续比较当前运算符和新的栈顶运算符,直到当前运算符的优先级高于栈顶运算符或者栈为空,再把当前运算符入栈。
比如说,读到“+”的时候,栈为空,那就把“+”入栈。
接着读到“”,因为“”的优先级高于“+”,所以把“”入栈。
再读到“”,因为“”的优先级低于“”,所以把“”出栈并输出,然后再比较“”和“+”,因为“”的优先级高于“+”,所以把“”入栈。
当整个中缀表达式都读完之后,把栈中剩下的运算符依次出栈并输出。
按照这个步骤,咱们就能把“3 +4 2 1”这个中缀表达式转换为后缀表达式“3 4 2 +1 ”。
在实际的编程中,实现这个转换过程可能会用到一些数据结构和算法的知识。
比如说,用数组或者链表来实现栈,用循环和条件判断来处理表达式的读取和转换。
再举个例子,“(2 +3) 4 5”。
中缀表达式转后缀表达式详解
中缀表达式转后缀表达式详解中缀表达式和后缀表达式是两种常见的数学表达式形式。
中缀表达式是我们通常使用的表达式形式,即运算符位于操作数的中间,例如:'2 + 3'。
而后缀表达式(也称为逆波兰表达式)是一种更为简洁和易于计算机处理的表达式形式,其中运算符位于操作数的后面,例如:'2 3 +'。
将中缀表达式转换为后缀表达式的主要目的是减少表达式的复杂性,使其更容易被计算机处理。
转换过程涉及使用栈来保存运算符,并按照一定的规则重新排列表达式中的元素。
下面是将中缀表达式转换为后缀表达式的步骤:1. 创建一个空栈和一个空列表,用于保存转换后的后缀表达式。
2. 从左到右遍历中缀表达式的每个元素。
3. 如果遇到操作数(数字),将其添加到后缀表达式列表中。
4. 如果遇到左括号'(',将其推入栈中。
5. 如果遇到操作符,比较其与栈顶操作符的优先级。
a. 如果栈为空或栈顶为左括号'(',则将操作符推入栈中。
b. 如果操作符的优先级大于栈顶操作符的优先级,将其推入栈中。
c. 如果操作符的优先级小于或等于栈顶操作符的优先级,将栈顶操作符弹出并添加到后缀表达式列表中,然后将操作符推入栈中。
6. 如果遇到右括号')',将栈中的操作符弹出并添加到后缀表达式列表中,直到遇到左括号'('。
注意,左右括号不会被添加到后缀表达式中。
7. 当中缀表达式遍历完毕后,将栈中剩余的操作符依次弹出并添加到后缀表达式列表中。
8. 后缀表达式列表即为转换后的后缀表达式。
例如,将中缀表达式 '2 + 3 * 4' 转换为后缀表达式的步骤如下:中缀表达式:2 + 3 * 4后缀表达式列表(初始为空):[]遍历中缀表达式的每个元素:1. 遇到操作数2,添加到后缀表达式列表中:[2]2. 遇到操作符+,将其推入栈中:[+]3. 遇到操作数3,添加到后缀表达式列表中:[2, 3]4. 遇到操作符*,将其推入栈中:[+, *]5. 遇到操作数4,添加到后缀表达式列表中:[2, 3, 4]6. 中缀表达式遍历完毕,将栈中剩余的操作符弹出并添加到后缀表达式列表中:[2, 3, 4, *]最终转换后的后缀表达式为:'2 3 4 * +'后缀表达式的计算可以通过遍历列表中的元素来完成。
中缀表达式转换成后缀表达式
实验三中缀表达式转换成后缀表达式,然后按后缀表达式计算实验一、实验目的:对所学数据结构知识进行温习,比如栈和队列的顺序存储结构和链式结构、大体操作进行温习;将一个中缀表达式转换成后缀表达式,然后按后缀表达式计算进行分析与设计,上机调试,最终达到应用的目。
二、实验要求:要求对中缀表达式转换成后缀表达式,然后按后缀表达式计算作设计性实验,并上机运行,撰写实验报告。
三、实验内容:将一个中缀表达式转换成后缀表达式,然后按后缀表达式计算,例如:5+(4+2)/2-3*2。
四、实验环境:Windows XP + VC++6.0开发环境。
五、上机调试代码:# include<stdio.h># include<stdlib.h>typedef char typedata1;typedef int typedata2;typedef struct charnode{typedata1 data;struct charnode *next;}charstack;typedef struct intnode{typedata2 data;struct intnode *next;}intstack;char s[100];charstack *creat(){ charstack *head;head=(charstack *)malloc(sizeof(charstack));head->data='#';head->next=0;return head;}intstack *intcreat(){ intstack *head;head=(intstack *)malloc(sizeof(intstack));head->data=0;head->next=0;return head;}charstack *push(charstack *top,char x){charstack *p;p=(charstack *)malloc(sizeof(charstack));p->data=x;p->next=top;top=p;return top;}intstack *intpush(intstack *top,int x){intstack *p;p=(intstack *)malloc(sizeof(intstack));p->data=x;p->next=top;top=p;return top;}typedata1 top(charstack *top){return top->data;}typedata2 inttop(intstack *top){return top->data;}char compare(char x1,char x2){char m;int m1,m2;if(x1=='+'||x1=='-') m1=0;else if(x1=='*'||x1=='/') m1=1;else if(x1=='(') m1=2;if(x2=='+'||x2=='-') m2=0;else if(x2=='*'||x2=='/') m2=1;else if(x2=='(') m2=2;if(m1>m2) m='>';else if(m1<m2) m='<';else m='=';return m;}charstack *popl(charstack *top){ charstack *p;if(top==0)printf("下溢!");else{p=top;top=top->next;free(p);return top;}}intstack *intpopl(intstack *top){ intstack *p;if(top==0)printf("下溢!");else{p=top;top=top->next;free(p);return top;}}void display(char m[],int n){int i;for(i=0;i<=n;i++)printf("%c",m[i]);}int change(char a[],int n){int i;int j=0;char x1,x2,bj;charstack *q;q=creat();for(i=0;i<n;i++){if(a[i]<='9'&&a[i]>='0'){s[j]=a[i];j=j+1;if(a[i+1]>'9'||a[i+1]<'0'){s[j]=' ';j=j+1;}}else{x1=a[i];x2=top(q);if(x2=='#')q=push(q,x1);else{if(x1==')'){while(top(q)!='('){s[j]=top(q);j=j+1;q=popl(q);}q=popl(q);}else{bijiao:bj=compare(x1,x2);switch(bj){case '>':q=push(q,x1);break;case '<':if(x2!='('){s[j]=top(q);j=j+1;q=popl(q);x2=top(q);if(x2!='#') goto bijiao; else q=push(q,x1);break;}else q=push(q,x1);break;case '=':s[j]=top(q);j=j+1;q=popl(q);q=push(q,x1);break;}}}}}while(top(q)!='#'){s[j]=top(q);j=j+1;q=popl(q);}return j;}int calculator(char s[],int n){int i,x1,x2,x;intstack *q;q=intcreat();for(i=0;i<=n;i++){if(s[i]==' ') i=i+1;if(s[i]<='9'&&s[i]>='0'){x1=(int)s[i]-48; while(s[i+1]<='9'&&s[i+1]>='0'){x1=10*x1+(int)s[i+1]-48;i=i+1;}q=intpush(q,x1); }else if(s[i]=='+'){ x2=inttop(q);q=intpopl(q);x1=inttop(q);q=intpopl(q);q=intpush(q,x1+x2); }else if(s[i]=='-'){ x2=inttop(q);q=intpopl(q);x1=inttop(q);q=intpopl(q);q=intpush(q,x1-x2); }else if(s[i]=='*'){ x2=inttop(q);q=intpopl(q);x1=inttop(q);q=intpopl(q);q=intpush(q,x1*x2); }else if(s[i]=='/'){ x2=inttop(q);q=intpopl(q);x1=inttop(q);q=intpopl(q);q=intpush(q,x1/x2);}}x=inttop(q);return x;}void main(){int i,k;char f[100];printf("请输入中缀表达式(输入#终止):\n");for(i=0;i<100;i++){scanf("%c",&f[i]);if(f[i]=='#')break;}printf("\n后缀表达式为:");k=change(f,i);display(s,k);printf("\n\n计算结果为:%d\n\n",calculator(s,k)); }六、实验结果分析:1)实验运行结果及测试截图如下:2)本实验对字符也一样能得出后缀表达式,可是没有赋具体值,故不能算结果,同时呢也会弹出运用程序错误提示,测试截图如下:3)实验改良,若是本实验能在改良为,当输入为字符时自动提示为此字符赋值,那么此程序也将能计算出带有字符的的表达式的结果,同时本实验也能够通过其它算法实现。
练手系列(3)中缀表达式转后缀表达式
练⼿系列(3)中缀表达式转后缀表达式 最近在看数据结构和算法时,看到了中缀表达式和后缀表达式,感觉蛮有意思的,于是⾃⼰实现了⼀下,算是⼀种锻炼。
①⾸先,中缀表达式就是我们平时见惯了的算术式,⽐如:5+3这样的就是中缀表达式,⽽后缀表达式呢,就是53+这样的。
因为转为后缀表达式后,算术式的计算会相对简单⼀些,可以⽤栈来实现。
分析图如下:这种后缀表达式计算的最⼤的优点就是不⽤知道什么优先级。
②好,下⾯我们来看⼀下怎么从中缀表达式(5+3)变为后缀表达式(53+):好了,以上两张图⽚就是后缀表达式的相关分析。
下⾯上具体代码:1import java.util.Stack;23public class Calculate {4// 定义操作符号5private static final char PLUS = '+';6private static final char MINUS = '-';7private static final char MULTIPLY = '*';8private static final char DIVIDE = '/';9private static final char LEFT_PARENTHESIS = '(';10private static final char RIGHT_PARENTHESIS = ')';1112public static void main(String[] args) {13 String infix = "(3+(2-1))*5";14 String postfix = convert(infix);15 System.out.println(postfix);16 analysePostfix(postfix);17 }1819// 计算后缀表达式20public static void analysePostfix(String postfix) {21 Stack<Double> stack = new Stack<Double>();22char[] chs = postfix.toCharArray();23for (int i = 0; i < chs.length; i++) {24if (chs[i] != PLUS && chs[i] != MINUS && chs[i] != MULTIPLY25 && chs[i] != DIVIDE) {26// 如果读取到的是数字,则加到栈中27 stack.push(Double.valueOf(String.valueOf(chs[i])));28 } else {29// 如果读取到的是操作符,则从栈中弹出两个数字,并执⾏运算30double b = (double) stack.pop();31double a = (double) stack.pop();32char operator = chs[i];33double result = calculate(a, b, operator);34 stack.push(result);35 }36 }37 System.out.println("result is : " + stack.pop());38 }3940public static double calculate(double a, double b, char operator) {41switch (operator) {42case PLUS:43return a + b;44case MINUS:45return a - b;46case MULTIPLY:47return a * b;48case DIVIDE:49return a / b;50 }51return 0;52 }5354// 中缀到后缀的转换55public static String convert(String infix) {56 Stack<Character> vector = new Stack<Character>();57char[] chs = infix.toCharArray();58 StringBuffer postfix = new StringBuffer();59for (int i = 0; i < chs.length; i++) {60// 如果是数字,直接插⼊表达式中61if (chs[i] != PLUS && chs[i] != MINUS && chs[i] != MULTIPLY62 && chs[i] != DIVIDE && chs[i] != LEFT_PARENTHESIS63 && chs[i] != RIGHT_PARENTHESIS) {64 postfix.append(String.valueOf(chs[i]));65 } else {66// 如果是左括号,直接压⼊栈中67if (LEFT_PARENTHESIS == chs[i]) {68 vector.push(chs[i]);69continue;70 }71// 如果是右括號,則去除棧裏⾯的左括號之上的所有操作符號72if (RIGHT_PARENTHESIS == chs[i]) {73while (LEFT_PARENTHESIS != vector.peek()) {74 postfix.append(vector.pop());75 }76 vector.pop();77 }78// 如果当前读到的操作符和栈⾥⾯的操作符⼀样,那么直接加到后缀表达式中 79if (vector.size() > 0 && chs[i] == vector.peek()) {80 postfix.append(String.valueOf(chs[i]));81 } else if (vector.size() == 0 || chs[i] != vector.peek()) {82// 如果是乘号或者除号,直接压⼊栈中83if (MULTIPLY == chs[i] || DIVIDE == chs[i]) {84 vector.push(chs[i]);85 }86if (PLUS == chs[i] || MINUS == chs[i]) {87if (vector.size() > 088 && (vector.peek() == MULTIPLY || vector.peek() == DIVIDE)) {89 postfix.append(vector.pop().toString());90 vector.push(chs[i]);91 } else {92 vector.push(chs[i]);93 }94 }95 }96 }97// 如果已经读完了中缀表达式,则弹出栈中所有操作符并加⼊到后缀表达式中 98if (i == chs.length - 1) {99for (int j = vector.size(); j > 0; j--) {100 postfix.append(vector.pop().toString());101 }102 }103 }104return postfix.toString();105 }106 }。
中缀表达式转后缀表达式实验报告
实验题目:中缀表达式转后缀表达式实验报告一、实验目的本实验旨在通过编写程序,掌握中缀表达式转后缀表达式的算法,并进行实际的转换操作,加深对中缀表达式和后缀表达式的理解,提高编程能力。
二、实验原理1. 中缀表达式:中缀表达式是我们平常常见的算术表达式,如 a + b * c。
2. 后缀表达式(逆波兰表达式):后缀表达式是没有括号,而操作符号放在两个操作数之后的表达式,如 a b c * +。
中缀表达式转后缀表达式的算法步骤如下:- 从左到右遍历中缀表达式的每个数字和操作符;- 如果是数字,则直接输出到后缀表达式;- 如果是操作符,则将其与栈顶元素进行比较,如果比栈顶元素的优先级高或相等,则将栈顶元素弹出,输出到后缀表达式中,直到栈顶元素优先级低于该操作符,然后将该操作符压入栈中;- 遍历完中缀表达式后,将栈中的操作符依次弹出,输出到后缀表达式中。
三、实验过程1. 设计程序我们设计了一个简单的算法,实现中缀表达式转后缀表达式的功能。
我们采用了栈的数据结构来辅助转换过程,具体实现如下:```pythonclass InfixToPostfix:def __init__(self):self.stack = []self.output = []def is_higher_precedence(self, op1, op2):precedence = {'+': 1, '-': 1, '*': 2, '/': 2, '^': 3}return precedence[op1] >= precedence[op2]def convert(self, infix):for char in infix:if char.isalnum():self.output.append(char)elif char in '+-*/^':while self.stack andself.is_higher_precedence(self.stack[-1], char):self.output.append(self.stack.pop())self.stack.append(char)while self.stack:self.output.append(self.stack.pop())return ''.join(self.output)```2. 编写测试用例为了验证程序的正确性,我们编写了一系列的测试用例,包括简单的表达式(如 a+b*c)、带括号的表达式(如 (a+b)*c)、带有多位数的表达式(如 12+34*56)等多种情况。
中缀表达式转前后缀表达式的手工求法
中缀表达式转前后缀表达式的⼿⼯求法⽆论是⾯试还是考研,数据结构中都会出现⼀类题型,就是已知中缀表达式求其前缀表达式或者后缀表达式。
这类题型多遇见⼏个,多做⼏个掌握以下⽅法,就没问题了。
先说⼀个⽐较简单的,个⼈还是⽐较倾向于这种的⼆叉树表⽰法:表达式A*B:左⼦树为表达式A,右⼦树为表达式B,可以先求左⼦树所表⽰的表达式的值,再求右⼦树所表⽰的表达式的值,最后⼆者相乘。
注意,所画出的⼆叉树,它的叶⼦节点为数值,⾮叶⼦节点是运算符。
画出⼆叉树以后,依次进⾏前序遍历和后序遍历,可以得出前缀表达式和后缀表达式。
例如美团曾经出过的⼀个笔试题⽬:解答:根据题⽬,我们可以画出⼆叉树,如图所⽰:然后根据后序遍历,即可得出后缀表达式,前序遍历即可得出前缀表达式~另外⼀种办法是利⽤栈进⾏操作,利⽤栈进⾏操作的这⼀种办法和许多书上不太⼀样,这是我在其他⼤⽜的博客⾥学习的,那么在这⾥附上⼤⽜写的博客的⽹址:顺带把⼤⽜总结的内容⾃⼰⼩结⼀下:将中缀表达式转换为前缀表达式:遵循以下步骤:(1) 初始化两个栈:运算符栈S1和储存中间结果的栈S2;(2) 从右⾄左扫描中缀表达式;(3) 遇到操作数时,将其压⼊S2;(4) 遇到运算符时,⽐较其与S1栈顶运算符的优先级:(4-1) 如果S1为空,或栈顶运算符为右括号“)”,则直接将此运算符⼊栈;(4-2) 否则,若优先级⽐栈顶运算符的较⾼或相等,也将运算符压⼊S1;(4-3) 否则,将S1栈顶的运算符弹出并压⼊到S2中,再次转到(4-1)与S1中新的栈顶运算符相⽐较;(5) 遇到括号时:(5-1) 如果是右括号“)”,则直接压⼊S1;(5-2) 如果是左括号“(”,则依次弹出S1栈顶的运算符,并压⼊S2,直到遇到右括号为⽌,此时将这⼀对括号丢弃;(6) 重复步骤(2)⾄(5),直到表达式的最左边;(7) 将S1中剩余的运算符依次弹出并压⼊S2;(8) 依次弹出S2中的元素并输出,结果即为中缀表达式对应的前缀表达式。
数据结构中缀式中缀表达式改后缀表达式并求值
《数据结构》课程设计报告课程设计题目:中缀表达式改后缀表达式并求值一. 实验目的·掌握栈的特征及基本操作,如入栈、出栈等,栈的顺序存储结构和链式存储结构的实现,以便在实际问题中灵活应用。
·掌握栈的典型应用——中缀表达式转后缀表达式,并利用后缀表达式求值。
二. 实验内容(一)中缀表达式转后缀表达式的方法:1.遇到操作数:直接输出(添加到后缀表达式中)2.栈为空时,遇到运算符,直接入栈3.遇到左括号:将其入栈4.遇到右括号:执行出栈操作,并将出栈的元素输出,直到弹出栈的是左括号,左括号不输出。
5.遇到其他运算符:加减乘除:弹出所有优先级大于或者等于该运算符的栈顶元素,然后将该运算符入栈6.最终将栈中的元素依次出栈,输出。
(二)三. 实验分析程序源码(要求对每个函数及主要代码加上注释语句),源码出处。
//// main.c// 后缀表达式求值//// Created by 颜彦闻on 14/12/2.// Copyright (c) 2014年颜彦闻. All rights reserved.//#include <stdio.h>#include <stdlib.h>#define StackSize 100#define QueueSize 100typedef char DataType;typedef struct{char data[100];int front,rear;}SeqQueue; //定义队列类型void InitQueue(SeqQueue *Q) //初始化队列{Q->front=0;Q->rear=0;}int QueueEmpty(SeqQueue Q) //判空{return Q.rear==Q.front;}void EnQueue(SeqQueue *Q,DataType x) //元素入队列函数{if((Q->rear+1)%QueueSize==Q->front)printf("Queue overflow");else{Q->data[Q->rear]=x;Q->rear=(Q->rear+1)%QueueSize;}}DataType DeQueue(SeqQueue *Q){char x;if(QueueEmpty(*Q))return0;else{x=Q->data[Q->front];Q->front=(Q->front+1)%QueueSize;return x;}}//栈的相关操作typedef struct{DataType data[100];int top;}SeqStack;void InitStack(SeqStack *S) //栈的初始化{S->top=-1;}void Push(SeqStack *S,DataType x) //进栈函数{if(S->top==StackSize-1)printf("stack overflow");else{S->top=S->top+1;S->data[S->top]=x;}}DataType Pop(SeqStack *S) //退栈顶指针函数{if(S->top==-1){printf("stack underflow");return0;}elsereturn S->data[S->top--];}DataType GetTop(SeqStack S) //取栈顶元素{if(S.top==-1){printf("stack empty");return0;}elsereturn S.data[S.top];}int Priority(DataType op) //求运算符优先级函数{switch(op){case'(':case'#':return0;case'-':case'+':return1;case'*':case'/':return2;}return -1;}void CTPostExp(SeqQueue *Q){SeqStack S;char c,t;InitStack(& S);Push(&S,'#');do{c=getchar();switch(c){case' ':break;case'1':case'2':case'3':case'4':case'5':case'6':case'7':case'8':case'9':EnQueue(Q ,c);break;case'(':Push(&S,c);break;case')':case'#':{do{t=Pop(&S);if(t!='('&&t!='#')EnQueue(Q ,t);}while(t!='('&&S.top!=-1);break;}case'+':case'-':case'*':case'/':while(Priority(c)<=Priority(GetTop(S))){t=Pop(&S);EnQueue(Q,t);}Push(&S,c);break;}}while(c!='#');}DataType CPostExp(SeqQueue Q){SeqStack S;char ch;int x,y;InitStack(&S);while(!QueueEmpty(Q)){ch=DeQueue(&Q);if(ch>='0'&&ch<='9')Push(&S,ch);else{y=Pop(&S)-'0';x=Pop(&S)-'0';switch(ch){case'+': Push(&S,(char)(x+y+'0'));break;case'-': Push(&S,(char)(x-y+'0'));break;case'*': Push(&S,(char)(x*y+'0'));break;case'/': Push(&S,(char)(x/y+'0'));break;}}}return GetTop(S);}int main(int argc, char *argv[]){SeqQueue Q;InitQueue(&Q);printf("输入表达式:\n");CTPostExp(&Q);printf("结果:%c\n",CPostExp(Q));printf("后缀表达式:");while(!QueueEmpty(Q))printf("%2c",DeQueue(&Q));printf("\n");system("PAUSE");return0;}四. 算法时间复杂度。
大数据结构中缀表达式转后缀表达式
中缀转后缀,后缀求值13070319张乐2015.4.211、需求分析明确规定:需要运用栈来实现对中缀表达式转换为后缀表达式,并且再次输入后缀表达式,得出结果。
输入形式、输入值的范围;中缀表达式的输入,操作数必须不为负数,并且表达式以=结束输入输出形式;第一次输出后缀表达式,接着输出后缀表达式求得的值程序功能;中缀表达式转换为后缀表达式,后缀表达式求值测试数据:10(20-10)+10=2、概要设计ADT定义:class arrStack{private:int mSize; //栈最多存放元素个数int top; //栈顶指针T *st; //存栈元素的数组public:arrStack(int sizee) { //创建定长顺序栈的实例mSize = sizee;top = -1;st =new T[mSize];}arrStack( ) {}~arrStack( ) {}void clear( ) { }bool isEmpty( ){}bool push(const T item){}bool pop(T& item) {} T& gettop() {}bool input(){}int trans(){}bool Caculator(){ }}主程序流程:各程序模块间的调用关系;3、详细设计实现ADT定义的数据类型:arrStack(int sizee) { //创建定长顺序栈的实例mSize = sizee;top = -1;st =new T[mSize];}arrStack( ) { //清空top = -1;}~arrStack( ) { //销毁delete [ ]st;}void clear( ) { //清空top = -1;}bool isEmpty( ){ //若栈已空返回trueif(top==-1)return true;return false;}bool push(const T item) //入栈 O(1){/*if (top==(mSize-1)){ //若上溢T *newst = new T[ mSize*2 ]; //扩容到2倍for(int i = 0; i<= top; i++) //复制newst[ i ]= st[ i ];delete [ ]st; //释放旧空间st = newst; //恢复stmSize *=2; //改写mSize }*/st[ ++top ] = item; //插入item return true;}bool pop(T& item) //出栈 O(1){if (top==-1){cout<<"空栈不能删"<<endl;return false;}else{item=st[ top-- ];return true;}}T& gettop() //取栈顶O(1){if (top==-1){cout<<"空栈不能读取"<<endl;}elsereturn st[ top ];}bool input(){char in;int i=0;cout<<"请您输入您要转换的前缀表达式"<<endl; cin>>in;while(in!='='){a[i]=in;cin>>in;i++;}a[i]='=';i=0;while(a[i]!='='){cout<<a[i];i++;}}int trans(){int i=0,j=0;char ch,e;ch=a[i];while(ch!='='){switch(ch){case '(':push(ch);break;case '+':case '-':case '/':case '*':{while(!isEmpty() && gettop()!='(' && gettop()<=ch){ e=gettop();b[j]=e;pop(e);j++;}push(ch);}break;case ')':if (!isEmpty()){while(gettop()!='('){e=gettop();b[j]=e;pop(e);j++;}}pop(e);break;default:if (ch>='0'<='9')b[j++]=ch;}ch=a[++i];}while(!isEmpty()){e=gettop();b[j++]=e;pop(e);}int k=0;cout<<endl<<"您得到的后缀表达式为:"<<endl;for (;k<j;k++)cout<<b[k]<<' ';return j;}};bool Caculator(){ //全局函数来计算后缀表达式arrStack<int>s(100);int newope,ope1,ope2,e;char c;cout<<endl<<"请您输入您得到的后缀表达式(以输入等号结束):"<<endl;while(cin>>c,c!='='){switch(c){case '+': ope2=s.gettop();s.pop(e);ope1=s.gettop();s.pop(e);s.push(ope1+ope2);break;case '-': ope2=s.gettop();s.pop(e);ope1=s.gettop();s.pop(e);s.push(ope1-ope2);break;case '*': ope2=s.gettop();s.pop(e);ope1=s.gettop();s.pop(e);s.push(ope1*ope2);break;case '/': ope2=s.gettop();s.pop(e);ope1=s.gettop();s.pop(e);s.push(ope1/ope2);break;default:cin.putback(c);cin>>newope;s.push(newope);break;}}cout<<endl<<"求得的值为:"<<endl;e=s.gettop();cout<<e<<endl;s.pop(e);}4、调试分析调试中遇到的问题、如何解决、对设计与实现的分析讨论;调试过程中出现了中缀表达式转换为后缀表达式转换错误的问题,原因是操作符号优先级判断判断错。
中缀表达式转后缀表达式并计算结果
中缀表达式转后缀表达式并计算结果⽬录1 栈的概念容器,先进后出规则;如图为表达式:a+(b*c) 逐个操作符、操作数⼊栈过程;出栈为该过程逆序2 何谓中缀表达式型如:a - b + c 的普通算术表达式,我们称之为中缀表达式。
3 后缀表达式(逆波兰)3.1 概念以及案例中缀表达式:a - b + c ,转化为后缀表达式:ab-c+;后缀表达式运算规则:1. 遇到操作数直接⼊栈,遇到操作符,从栈顶弹出两个操作数,并计算如下表达式结果压栈,直⾄最终弹出栈中最后⼀个数即停⽌算法,该记法的表达式称为后缀表达式后出栈操作数(两数中更靠近栈底者) (操作符[+_*/])先出栈操作数(栈顶)2. ab-c+计算过程如下图:3.2 求解⽅法⼊栈优先级{ [ ( > 乘= 除> 加= 减3.2.1 流程图弹出案例:扫描位优先级较⼩,扫描位为 " - "。
左括号虽然优先级⼤,但是左括号只在碰到,匹配的右括号时弹出3.2.2 推导相等优先级为何弹出栈顶只关注相同有优先级下是否弹出栈顶先加,后加减中缀表达式后缀表达式a +b +c abc++ 或 ab+c+a +b -c ab+c- 或 abc-+中缀表达式后缀表达式此例中,当需要判断操作符间优先级:栈顶为:+(加),栈外判断位:+ 或 - 。
此时若优先级相等,既可弹出栈顶操作符,也可不弹直接当前位压栈。
先减,后加减中缀表达式后缀表达式a -b +c ab-c+a -b -c ab-c-此例中,当需要判断操作符间优先级:栈顶为:-(减),栈外判断位:+ 或 - 。
此时若优先级相等,则只能弹出当前栈顶操作符。
先乘,后乘除中缀表达式后缀表达式a *b *c abc** 或 ab ca *b /c ab c/ 或 abc/此例中,当需要判断操作符间优先级:栈顶为:(乘),栈外判断位:或 / 。
此时若优先级相等,既可弹出栈顶操作符,也可不弹直接当前位压栈。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
中缀转后缀,后缀求值13070319乐2015.4.211、需求分析明确规定:需要运用栈来实现对中缀表达式转换为后缀表达式,并且再次输入后缀表达式,得出结果。
输入形式、输入值的围;中缀表达式的输入,操作数必须不为负数,并且表达式以=结束输入输出形式;第一次输出后缀表达式,接着输出后缀表达式求得的值程序功能;中缀表达式转换为后缀表达式,后缀表达式求值测试数据:10(20-10)+10=2、概要设计ADT定义:class arrStack{private:int mSize; //栈最多存放元素个数int top; //栈顶指针T *st; //存栈元素的数组public:arrStack(int sizee) { //创建定长顺序栈的实例mSize = sizee;top = -1;st =new T[mSize];}arrStack( ) {}~arrStack( ) {}void clear( ) { }bool isEmpty( ){}bool push(const T item){}bool pop(T& item) {}T& gettop() {}bool input(){}int trans(){}bool Caculator(){ }}主程序流程:各程序模块间的调用关系;3、详细设计实现ADT定义的数据类型:arrStack(int sizee) { //创建定长顺序栈的实例mSize = sizee;top = -1;st =new T[mSize];}arrStack( ) { //清空top = -1;}~arrStack( ) { //销毁delete [ ]st;}void clear( ) { //清空top = -1;}bool isEmpty( ){ //若栈已空返回trueif(top==-1)return true;return false;}bool push(const T item) //入栈O(1){/*if (top==(mSize-1)){ //若上溢T *newst = new T[ mSize*2 ]; //扩容到2倍for(int i = 0; i<= top; i++) //复制newst[ i ]= st[ i ];delete [ ]st; //释放旧空间st = newst; //恢复stmSize *=2; //改写mSize }*/st[ ++top ] = item; //插入itemreturn true;}bool pop(T& item) //出栈O(1){if (top==-1){cout<<"空栈不能删"<<endl;return false;}else{item=st[ top-- ];return true;}}T& gettop() //取栈顶O(1){if (top==-1){cout<<"空栈不能读取"<<endl;}elsereturn st[ top ];}bool input(){char in;int i=0;cout<<"请您输入您要转换的前缀表达式"<<endl;cin>>in;while(in!='='){a[i]=in;cin>>in;i++;}a[i]='=';i=0;while(a[i]!='='){cout<<a[i];i++;}}int trans(){int i=0,j=0;char ch,e;ch=a[i];while(ch!='='){switch(ch){case '(':push(ch);break;case '+':case '-':case '/':case '*':{while(!isEmpty() && gettop()!='(' && gettop()<=ch){ e=gettop();b[j]=e;pop(e);j++;}push(ch);}break;case ')':if (!isEmpty()){while(gettop()!='('){e=gettop();b[j]=e;pop(e);j++;}}pop(e);break;default:if (ch>='0'<='9')b[j++]=ch;}ch=a[++i];}while(!isEmpty()){e=gettop();b[j++]=e;pop(e);}int k=0;cout<<endl<<"您得到的后缀表达式为:"<<endl;for (;k<j;k++)cout<<b[k]<<' ';return j;}};bool Caculator(){ //全局函数来计算后缀表达式arrStack<int>s(100);int newope,ope1,ope2,e;char c;cout<<endl<<"请您输入您得到的后缀表达式(以输入等号结束):"<<endl;while(cin>>c,c!='='){switch(c){case '+': ope2=s.gettop();s.pop(e);ope1=s.gettop();s.pop(e);s.push(ope1+ope2);break;case '-': ope2=s.gettop();s.pop(e);ope1=s.gettop();s.pop(e);s.push(ope1-ope2);break;case '*': ope2=s.gettop();s.pop(e);ope1=s.gettop();s.pop(e);s.push(ope1*ope2);break;case '/': ope2=s.gettop();s.pop(e);ope1=s.gettop();s.pop(e);s.push(ope1/ope2);break;default:cin.putback(c);cin>>newope;s.push(newope);break;}}cout<<endl<<"求得的值为:"<<endl;e=s.gettop();cout<<e<<endl;s.pop(e);}4、调试分析调试中遇到的问题、如何解决、对设计与实现的分析讨论;调试过程中出现了中缀表达式转换为后缀表达式转换错误的问题,原因是操作符号优先级判断判断错。
算法时空分析;O(n)5、用户使用说明A.按照提示输入中缀表达式B.看到屏幕输出的后缀表达式C.将屏幕输出的后缀表达式再次按照屏幕提示输入D.看到屏幕输出的后缀表达式的值6、测试结果列出测试用输入、输出;7、源程序列出源程序清单:#include <iostream>#include<string.h>using namespace std;template <class T>class arrStack{private:int mSize; //栈最多存放元素个数int top; //栈顶指针T *st; //存栈元素的数组public:char a[100];char b[100];arrStack(int sizee) { //创建定长顺序栈的实例mSize = sizee;top = -1;st =new T[mSize];}arrStack( ) { //清空top = -1;}~arrStack( ) { //销毁delete [ ]st;}void clear( ) { //清空top = -1;}bool isEmpty( ){ //若栈已空返回trueif(top==-1)return true;return false;}bool push(const T item) //入栈O(1){/*if (top==(mSize-1)){ //若上溢T *newst = new T[ mSize*2 ]; //扩容到2倍for(int i = 0; i<= top; i++) //复制newst[ i ]= st[ i ];delete [ ]st; //释放旧空间st = newst; //恢复stmSize *=2; //改写mSize }*/st[ ++top ] = item; //插入item return true;}bool pop(T& item) //出栈O(1){if (top==-1){cout<<"空栈不能删"<<endl;return false;}else{item=st[ top-- ];return true;}}T& gettop() //取栈顶O(1){if (top==-1){cout<<"空栈不能读取"<<endl;}elsereturn st[ top ];}bool input(){char in;int i=0;cout<<"请您输入您要转换的前缀表达式"<<endl;cin>>in;while(in!='='){a[i]=in;cin>>in;i++;}a[i]='=';i=0;while(a[i]!='='){cout<<a[i];i++;}}int trans(){int i=0,j=0;char ch,e;ch=a[i];while(ch!='='){switch(ch){case '(':push(ch);break;case '+':case '-':case '/':case '*':{while(!isEmpty() && gettop()!='(' && gettop()<=ch){e=gettop();b[j]=e;pop(e);j++;}push(ch);}break;case ')':if (!isEmpty()){while(gettop()!='('){e=gettop();b[j]=e;pop(e);j++;}}pop(e);break;default:if (ch>='0'<='9')b[j++]=ch;}ch=a[++i];}while(!isEmpty()){e=gettop();b[j++]=e;pop(e);}int k=0;cout<<endl<<"您得到的后缀表达式为:"<<endl;for (;k<j;k++)cout<<b[k]<<' ';return j;}};bool Caculator(){ //全局函数来计算后缀表达式arrStack<int>s(100);int newope,ope1,ope2,e;char c;cout<<endl<<"请您输入您得到的后缀表达式(以输入等号结束):"<<endl;while(cin>>c,c!='='){switch(c){case '+': ope2=s.gettop();s.pop(e);ope1=s.gettop();s.pop(e);s.push(ope1+ope2);break;case '-': ope2=s.gettop();s.pop(e);ope1=s.gettop();s.pop(e);s.push(ope1-ope2);break;case '*': ope2=s.gettop();s.pop(e);ope1=s.gettop();s.pop(e);s.push(ope1*ope2);break;case '/': ope2=s.gettop();s.pop(e);ope1=s.gettop();s.pop(e);s.push(ope1/ope2);break;default:cin.putback(c);cin>>newope;s.push(newope);break;}}cout<<endl<<"求得的值为:"<<endl;e=s.gettop();cout<<e<<endl;s.pop(e);}main(){int i;arrStack<char> m(100);m.input();i=m.trans();Caculator();}。