大数据结构中缀表达式转后缀表达式

合集下载

将中缀表达式转换成后缀表达式的三种方法

将中缀表达式转换成后缀表达式的三种方法

将中缀表达式转换成后缀表达式的三种方法中缀表达式是我们平常最常见的表达式形式,但在计算机的运算过程中,我们常常需要将中缀表达式转换成后缀表达式,因为后缀表达式具有易于计算的特点。

那么,接下来我们将介绍三种将中缀表达式转换成后缀表达式的方法。

一、栈的方法这种方法是最常见的一种方法,也是比较易理解的一种方法。

我们可以借助栈来完成中缀表达式转换成后缀表达式的过程。

具体的操作如下: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.如果扫描字符是"+"或者"-",则⼀直出栈⾄栈顶元素为"+"或者"-"或者"("。

数据结构之中缀表达式转后缀表达式

数据结构之中缀表达式转后缀表达式
printf("No enough memory!");
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"。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 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();}。

相关文档
最新文档