用堆栈把中缀表达式转化为后缀表达式

来源:互联网 发布:java编码方式 编辑:程序博客网 时间:2024/04/28 22:07

参考文章:http://www.cnblogs.com/mygmh/archive/2012/10/06/2713362.html



中缀表达式转后缀表达式的方法:
1.遇到操作数:直接输出(添加到后缀表达式中)
2.栈为空时,遇到运算符,直接入栈
3.遇到左括号:将其入栈
4.遇到右括号:执行出栈操作,并将出栈的元素输出,直到弹出栈的是左括号,左括号不输出。
5.遇到其他运算符:加减乘除:弹出所有优先级大于或者等于该运算符的栈顶元素,然后将该运算符入栈
6.最终将栈中的元素依次出栈,输出。
例如
a+b*c+(d*e+f)*g ----> abc*+de*f+g*+

遇到a:直接输出:
后缀表达式:a
堆栈:空

遇到+:堆栈:空,所以+入栈
后缀表达式:a
堆栈:+
遇到b: 直接输出
后缀表达式:ab
堆栈:+
遇到*:堆栈非空,但是+的优先级不高于*,所以*入栈
后缀表达式: ab
堆栈:*+
遇到c:直接输出
后缀表达式:abc
堆栈:*+
遇到+:堆栈非空,堆栈中的*优先级大于+,输出并出栈,堆栈中的+优先级等于+,输出并出栈,然后再将该运算符(+)入栈
后缀表达式:abc*+
堆栈:+
遇到(:直接入栈
后缀表达式:abc*+
堆栈:(+
遇到d:输出
后缀表达式:abc*+d
堆栈:(+
遇到*:堆栈非空,堆栈中的(优先级小于*,所以不出栈
后缀表达式:abc*+d
堆栈:*(+
遇到e:输出
后缀表达式:abc*+de
堆栈:*(+
遇到+:由于*的优先级大于+,输出并出栈,但是(的优先级低于+,所以将*出栈,+入栈
后缀表达式:abc*+de*
堆栈:+(+
遇到f:输出
后缀表达式:abc*+de*f
堆栈:+(+
遇到):执行出栈并输出元素,直到弹出左括号,所括号不输出
后缀表达式:abc*+de*f+
堆栈:+
遇到*:堆栈为空,入栈
后缀表达式: abc*+de*f+
堆栈:*+
遇到g:输出
后缀表达式:abc*+de*f+g
堆栈:*+
遇到中缀表达式结束:弹出所有的运算符并输出
后缀表达式:abc*+de*f+g*+
堆栈:空

 



#include "stdafx.h"


#include <stdio.h>
#include <stddef.h>
#include <string.h>
#include <stdlib.h>
#define MAXSIZE 100
typedef struct Stack
{int arr[MAXSIZE];
int top;
}Stack;
Stack stack,stack2;
int pop(Stack *stack)
{  int ret;
if( stack->top<=-1)
  return -1;
 else
 {ret=stack->arr[stack->top]; stack->top--;}
 return ret;
}
int topVal(Stack *stack)
{
  return stack->arr[stack->top];
}


int position(Stack *stack)
{
  return stack->top;
}
int isEmpty(Stack *stack)
{
if (stack->top>-1) return 0;
else return 1;
}
void push(int num,Stack *stack)
{if( stack->top>=MAXSIZE)
  return ;
 else
 {stack->top++;
 (stack->arr[stack->top]=num);
 }
}
typedef struct Node
{
union
{char exp;
int a;
} data;
 struct Node *next;
}Node;


int isExpression(int tmpExp){
if(tmpExp=='+'||tmpExp=='-'||tmpExp=='/'||tmpExp=='*'||tmpExp=='('||tmpExp==')')
  return 1;
else
return 0;
}
int isSuperior(int tmpExp,int tmpExp2){


if(tmpExp2=='('||(tmpExp=='/'||tmpExp=='*')&&(tmpExp2=='+'||tmpExp2=='-'))  // 左括号是优先级最低的(在堆栈里),
 return 1;
else return 0;


}
void printNode(Node* node)
{
if(node)
{char tmpExp=node->data.exp;
 if(isExpression(tmpExp))
  printf("%c",node->data.exp);
 else
   printf("%d",node->data.a);
if(node)
  printNode(node->next);
}
}


//转换为后缀表达式
Node * head=NULL;
Node *  surfixExpCalculate(Node* node)
{
       Node * newnode=(Node*)malloc(sizeof(Node));
  Node * tmpNode;
head=tmpNode=newnode;
head->data.exp=' ';
head->data.a=0;
while(node=node->next)
{
  
       
if(!(isExpression(node->data.exp)))                //参考文章有误,这里是把数值直接保存到后缀表达式链表里,而stack堆栈只用来保存表达式
{
 newnode=(Node*)malloc(sizeof(Node)); 
                                   newnode->next=0;
 newnode->data.a=node->data.a;   
    tmpNode->next=newnode;
                 tmpNode=newnode;
}else
{ char tmpExp=node->data.exp;
if(tmpExp=='(')         //左括号直接入栈,
{
  push(tmpExp,&stack);

}else if(tmpExp==')') //碰到右括号,把堆栈里的表达式全部弹出,直到遇到左括号
{
while(!isEmpty(&stack)&&topVal(&stack)!='(')
{
newnode=(Node*)malloc(sizeof(Node));
                            newnode->next=0;
newnode->data.exp=pop(&stack);
     
   tmpNode->next=newnode;
                            tmpNode=newnode;
}
pop(&stack);   // //左括号弹出栈,
}
else
{
if(isEmpty(&stack)||isSuperior(tmpExp,topVal(&stack)))  //堆栈空或者表达式比栈顶高,入栈
{
push(tmpExp,&stack);
}
else
{
   while(!isEmpty(&stack)&&!isSuperior(tmpExp,topVal(&stack))) //堆栈非空或者表达式优先级比栈顶底,顶底出栈,计算表达式,知道遇到比栈顶优先高为止

newnode=(Node*)malloc(sizeof(Node));
                            newnode->next=0;
newnode->data.exp=pop(&stack);
     
   tmpNode->next=newnode;
                            tmpNode=newnode;

};
 
push(tmpExp,&stack);
}
}


}


}
while (!isEmpty(&stack))
    {
newnode=(Node*)malloc(sizeof(Node));
                            newnode->next=0;
newnode->data.a=pop(&stack);
     
   tmpNode->next=newnode;
                            tmpNode=newnode;
    }


return head;


}


typedef struct Stack2                       //为了重新计算后缀表达式数值,重新定义了含double类型成员的stack2
{double arr[MAXSIZE];
int top;
}Stack2; 
void push(double num,Stack2 *stack)
{if( stack->top>=MAXSIZE)
  return ;
 else
 {stack->top++;
 (stack->arr[stack->top]=num);
 }
}


double pop(Stack2 *stack)
{  double ret;
if( stack->top<=-1)
  return -1;
 else
 {ret=stack->arr[stack->top]; stack->top--;}
 return ret;
}
// 后缀表达式求值程序
double postFixEval(Node * head)
{ double val=0;
  Node * node=head->next;
  Stack2 stack2;  //用到another堆栈,计算后缀表达式结果
  stack2.top=-1;
while(node)
{
if(!isExpression(node->data.exp))
{
push(node->data.a,&stack2);
}
else
{
double op1=pop(&stack2);
double op2=pop(&stack2);


switch (node->data.exp)
{
case '+':
val = op1 + op2;
break;
case '-':
val = op2 - op1;
break;
case '*':
val = op1 * op2;
break;
case '/':
val = op2 / op1;
break;
}
                push(val,&stack2);
}
node=node->next;


}


return val=pop(&stack2);
}



int main(int argc, char* argv[])
{ stack.top=-1;
stack2.top=-1;
Node * head;
int i=0,length=0;
 char buf[1024];
char* tmpExp,sep[]=" ";
char *p=NULL;
  head=(Node*)malloc(sizeof(Node));
  head->data.exp=' ';
  head->data.a=0;
 head->next=0;


gets(buf);
tmpExp=buf;
Node* tmpExpNode=head;
while(p=strtok(tmpExp,sep))
{


  Node * node=(Node*)malloc(sizeof(Node));
  node->next=0;
 // printf("%s",p); p is a point to  string (not a point to a char)
if(strcmp(p,"+")==0||strcmp(p,"+")==0||strcmp(p,"-")==0||strcmp(p,"*")==0||strcmp(p,"/")==0||strcmp(p,"(")==0||strcmp(p,")")==0)
sscanf(p,"%c",&node->data.exp);
else
 sscanf(p,"%d",&node->data.a);
   
tmpExpNode->next=node;
   tmpExpNode=node;
   tmpExp=0;
 }
head=surfixExpCalculate(head);
head=surfixExpCalculate(head);
//printNode(head->next);

postFixEval(head);
  return 0;
}

0 0
原创粉丝点击