上一篇文章我们讲了怎样把中缀表达式转化为后缀表达式,关于后缀表达式的计算过程我们也举了一个简单的例子(想看例子的朋友点这里# 数据结构题目笔记-03-中缀表达式转为后缀表达式 C语言)。
在这里我们再讲一个稍微复杂的例子并附上操作步骤
例子假设我们要计算一个式子:'9 3 1 - 3 x + 10 2 / +'
| 扫描到的元素 | 数字堆栈S(堆底->堆顶) | 解释 |
|---|---|---|
| 9 | 9 | 压入 |
| 3 | 9 3 | 压入 |
| 1 | 9 3 1 | 压入 |
| - | 9 2 | 遇到运算符 '-', 压出 1 3 实现操作 3 - 1 =2,并压入堆栈S |
| 3 | 9 2 3 | 压入 |
| x | 9 6 | 遇到操作符 'x', 压出 3 2 实现操作 3 x 2 =6,并压入堆栈S |
| + | 15 | 遇到操作符 '+', 压出 6 9 实现操作 6 + 9=15,并压入堆栈S |
| 10 | 15 10 | 压入 |
| 2 | 15 10 2 | 压入 |
| / | 15 5 | 遇到操作符 '/', 压出 2 10 实现操作 10 / 2=5,并压入堆栈S |
| + | 20 | 遇到操作符 '+', 压出 5 15 实现操作 15 + 5=20,并压入堆栈S |
| 扫描结束 | 20 | 结果 |
代码实现
定义一个堆栈
typedef struct SNode *Stack;
typedef int Position;
typedef int ElementType;
#define MAXSIZE 30
struct SNode{
ElementType Data[MAXSIZE];
Position Top;
};
初始化一个堆栈
Stack Create(){
Stack S;
S=(Stack)malloc(sizeof (struct SNode));
S->Top=-1;
return S;
}
压入堆栈
void Push(ElementType X,Stack S){
if(IsFull(S)){
printf("堆栈已满!\n");
return;
} else{
S->Top++;
S->Data[S->Top]=X;
}
}
压出堆顶元素
ElementType Pop(Stack S){
ElementType X;
if(IsEmpty(S)){
printf("堆栈已空!\n");
return -1;
} else{
X=S->Data[S->Top];
S->Top--;
return X;
}
}
后缀表达式的计算函数
int suffixExpressionCalculation(char* str){
int i=0;
Stack S;
S=Create();
ElementType number_to_push,num1,num2;
while (str[i] != '\0'){
if(str[i] != ' '){//跳过空格
if(str[i] >= '0' && str[i]<='9'){//是数字
number_to_push=0;
while (str[i] !=' ' && str[i]){
number_to_push=10*number_to_push+(str[i]-'0');
i++;//这里是是确保相连的数比如123,转化成123而不会分开
}
Push(number_to_push,S);
} else{
num2=Pop(S);
num1=Pop(S);
switch (str[i]) {
case '+':{
num1+=num2;
break;
}
case '-':{
num1-=num2;
break;
}
case '*':{
num1*=num2;
break;
}
case '/':{
num1/=num2;
break;
}
}
Push(num1,S);
}
}
i++;
}
num1=Pop(S);
return num1;
}
辅助函数
int IsFull(Stack S){
if(S->Top == MAXSIZE-1){
return 1;
}
return 0;
}
int IsEmpty(Stack S){
if(S->Top == -1){
return 1;
}
return 0;
}