解题思路:
这道题要求将一个正常的算术表达式(中缀表达式),转换成一个逆波兰式(后缀表达式)。 这道题也算是很经典的题了,还是使用了栈的思想,转换思路如下:
1.从左至右扫描一中缀表达式。 2.若读取的是操作数,则判断该操作数的类型,并将该操作数存入操作数堆栈 3.若读取的是运算符 ----(1) 该运算符为左括号"(",则直接存入运算符堆栈。 ----(2) 该运算符为右括号")",则输出运算符堆栈中的运算符到操作数堆栈,直到遇到左括号为止,此时抛弃该左括号。 ----(3) 该运算符为非括号运算符: --------( a ) 若运算符堆栈栈顶的运算符为左括号,则直接存入运算符堆栈。 --------( b ) 若比运算符堆栈栈顶的运算符优先级高,则直接存入运算符堆栈。 --------( c ) 若比运算符堆栈栈顶的运算符优先级低或相等,则输出栈顶运算符到操作数堆栈,直至运算符栈栈顶运算符低于(不包括等于)该运算符优先级,或为左括号,并将当前运算符压入运算符堆栈。 4.当表达式读取完成后运算符堆栈中尚有运算符时,则依序取出运算符到操作数堆栈,直到运算符堆栈为空。
具体操作见代码,代码中有部分注释。
题解代码:
#include <stdio.h>
#include <stdlib.h>
#define TRUE 1
#define FALSE 0
typedef int BOOL
;
typedef struct node
{
char data
;
struct node
*next
;
}Node
;
BOOL
IsEmpty(Node
*S
){
if(S
->next
== NULL){
return TRUE
;
}
return FALSE
;
}
void Push(Node
*S
, char x
){
Node
*temp
= (Node
*)malloc(sizeof(Node
));
temp
->data
= x
;
temp
->next
= S
->next
;
S
->next
= temp
;
}
void Pop(Node
*S
){
Node
*temp
= S
->next
;
S
->next
= S
->next
->next
;
free(temp
);
}
char GetTopElem(Node
*S
){
return S
->next
->data
;
}
BOOL
IsAlpha(char x
){
if(x
>='a'&&x
<='z' || x
>='A'&&x
<='Z'){
return TRUE
;
}
return FALSE
;
}
BOOL
IsLower(char x1
, char x2
){
if(x1
=='+' || x1
=='-'){
if(x2
=='*' || x2
=='/' || x2
=='('){
return TRUE
;
}
else{
return FALSE
;
}
}
else if(x1
=='*' || x1
=='/'){
if(x2
=='('){
return TRUE
;
}
else{
return FALSE
;
}
}
else if(x1
=='(' || x1
=='#'){
return TRUE
;
}
else{
return FALSE
;
}
}
BOOL
IsEqual(char x1
, char x2
){
if(x1
=='(' && x2
==')'){
return TRUE
;
}
return FALSE
;
}
int main(){
Node
*S
;
S
= (Node
*)malloc(sizeof(Node
));
S
->next
= NULL;
Push(S
,'#');
char c
;
char Top
;
BOOL Is_NoStillRightParentheses_Flag
= TRUE
;
while(TRUE
){
if(Is_NoStillRightParentheses_Flag
){
scanf("%c",&c
);
}
if(c
=='\n'){
break;
}
Is_NoStillRightParentheses_Flag
= TRUE
;
if(IsAlpha(c
)){
printf("%c",c
);
}
else{
Top
= GetTopElem(S
);
if(IsEqual(Top
,c
)){
Pop(S
);
}
else if(IsLower(Top
,c
)){
Push(S
,c
);
}
else{
printf("%c",Top
);
Pop(S
);
Is_NoStillRightParentheses_Flag
= FALSE
;
}
}
}
while(!IsEmpty(S
) && GetTopElem(S
)!='#'){
printf("%c",GetTopElem(S
));
Pop(S
);
}
return 0;
}