题目描述
算术表达式有前缀表示法、中缀表示法和后缀表示法等形式。日常使用的算术表达式是采用中缀表示法,即二元运算符位于两个运算数中间。请设计程序将中缀表达式转换为后缀表达式。
输入格式
输入在一行中给出不含空格的中缀表达式,可包含+、-、*、\以及左右括号(),表达式不超过20个字符。
输入格式
在一行中输出转换后的后缀表达式,要求不同对象(运算数、运算符号)之间以空格分隔,但结尾不得有多余空格。
输入样例
2+3*(7-4)+8/4
输出样例
2 3 7 4 - * + 8 4 / +
思路分析
这个题需要用到堆栈,我这里使用的是单向链表实现的堆栈,需要使用头插法,如果不了解可以去我上一篇博客------单链表逆转
先把输入用char数组存起来,然后从头判断,如果是数字就输出,如果是运算符就存到堆栈里,在存的时候判断一下优先级,要确认后一个的优先级比前一个的优先级高。如果遇到括号,就把"(“直接存到堆栈中,遇到”)"事,将()里面的运算符都取出,但是注意括号不要输出。
这个题主要是要考虑的情况比较多,比如首位为负数,只有一个数字等。。
源代码
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
/*
中缀字符串转后缀字符串
*/
#define ERROR -1
typedef int ElementType;
typedef struct Node *PtrToNode;
struct Node {
ElementType Data;
PtrToNode Next;
};
typedef PtrToNode List;
List Create();
bool isEmpty(List L);
bool Push(List L, ElementType x);
ElementType Pop(List L);
void Change(List L,char s[]);
int main()
{
List L=Create();
char s[21]={0};
scanf("%s",&s);
Change(L,s);
}
List Create()
{
List L = (List)malloc(sizeof(struct Node));
L->Next = NULL;
return L;
}
bool isEmpty(List L)
{
return (L->Next == NULL);
}
bool Push(List L, ElementType x)
{
bool flag = false;
List p = (List)malloc(sizeof(struct Node));
p->Data = x;
p->Next = L->Next;
L->Next = p;
flag = true;
return flag;
}
ElementType Pop(List L)
{
if(isEmpty(L))
{
printf("List is None\n");
return ERROR;
}
else
{
ElementType flag = L->Next->Data;
List p;
p = L->Next;
L->Next = p->Next;
free(p);
return flag;
}
}
void Change(List L,char s[]){
ElementType x;
int i=0;
while(s[i]!='\0'){
if(((i==0) && (s[i]=='-'||s[i]=='+'))||((s[i]>='0'&&s[i]<='9')||s[i]=='.')){
printf("%c",s[i]);
if((i==0) &&(s[i]=='-'||s[i]=='+')){
}else{
if(s[i+1]!=0||!isEmpty(L)){
printf(" ");
}
}
}else{
if(isEmpty(L)==true||s[i]=='('){
Push(L,s[i]);
}else if(s[i]=='*'||s[i]=='/'){
do{
x=Pop(L);
if(x=='+'||x=='-'){
Push(L,x);
Push(L,s[i]);
break;
}else if(x=='*'||x=='/'){
printf("%c ",x);
}else{
Push(L,x);
}
}while(!isEmpty(L)&&x!='(');
if(isEmpty(L)||x=='('){
Push(L,s[i]);
}
}else if(s[i]=='+'||s[i]=='-'){
do{
x=Pop(L);
if(x=='('){
Push(L,x);
}else{
printf("%c ",x);
}
}while(!isEmpty(L)&&x!='(');
if(isEmpty(L)||x=='('){
Push(L,s[i]);
}
}else if(s[i]==')'){
do{
x=Pop(L);
if(x!='(')
printf("%c ",x);
}while(x!='(');
}
}
i++;
}
while(!isEmpty(L)){
x=Pop(L);
printf("%c",x);
if(!isEmpty(L)){
printf(" ");
}
}
printf("\n");
}