主要思路是,将读取的中缀运算式转换为后缀运算式。分别设置一个数字栈和一个符号栈,边读取边处理。处理办法为:
1、读取到加减号时,将栈内高于或等于加减号优先级的符号逐一出栈进行运算,当前符号入栈。
2、读取到乘除号时,将栈内高于或等于乘除号优先级的符号逐一出栈进行运算,当前符号入栈。
3、读取到左括号时,直接入栈,正常进行下面的读取。
4、读取到右括号时,舍弃;将栈内符号逐一出栈进行运算,直到左括号出栈后舍弃。
5、读取完运算式后,符号栈不一定为空,需要逐一出栈运算。
代码如下:
#include <stdio.h>
#include <stdlib.h>
#include "stack.h"
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
int main(int argc, char *argv[]) {
int len=100,i=0;
char c;
char *str=(char *)malloc(sizeof(char)*len);
if(str==NULL){
printf("内存申请失败,程序退出");
}
while((c=getchar())!=EOF&&c!='\n'){ //读取运算式
if(i==len){
len*=2;
char *str1=(char *)realloc(str,len);
if(str1==NULL){
printf("内存申请失败,程序退出");
}
str=str1;
}
str[i++]=c;
}
str[i]='\0';
printf("%s\n",str);
int res=tosuffix(str,strlen(str));
printf("%d\n",res);
return 0;
}
#include "stack.h"
//typedef struct _node Node;
//typedef Node Stack;
//struct _node{
// int value;
// Node *next;
//};
Stack *creat_stack(){ //创建一个空栈
Stack *S=(Stack*)malloc(sizeof(Stack));
if(S==NULL){
printf("内存申请失败,程序结束");
exit(-1);
}
S->next=NULL;
return S;
}
bool isEmpty(Stack *S){ //判断是否为空栈
return S->next==NULL;
}
bool push(Stack *S,int value){ //入栈
Node *pNew=(Node*)malloc(sizeof(Node));
if(pNew==NULL){
printf("内存不足,入栈失败");
return false;
}
pNew->next=S->next;
pNew->value=value;
S->next=pNew;
return true;
}
int pop(Stack *S){ //出栈
int value=0;
if(!isEmpty(S)){
Node *temp=S->next;
S->next=temp->next;
value=temp->value;
free(temp);
}
return value;
}
int top(Stack *S){ //取栈顶值
if(!isEmpty(S))
return S->next->value;
else
return 0;
}
void clear(Stack *S){ //销毁栈
while(S->next){
Node *ptemp=S->next;
S->next=ptemp->next;
free(ptemp);
}
}
int count(Stack *S,char c){ //计算器代码,可以添加其他运算符号
int temp1=pop(S);
int temp2=pop(S);
int temp=0;
switch(c){
case '+':temp=temp2+temp1;break;
case '-':temp=temp2-temp1;break;
case '*':temp=temp2*temp1;break;
case '/':
if(temp1==0){
printf("ERROR\n");exit(-1);
}else temp=temp2/temp1;break;
}
return temp;
}
int tosuffix(char *str,int len){ //中缀表达式转化为后缀表达式
Stack *pSn=creat_stack(); //存数字的栈
Stack *pSs=creat_stack(); //存符号的栈
int i=0;
while(str[i]!='\0'){//判断读入字符串是否结束
if(str[i]=='+'||str[i]=='-'){ //加减号优先级相同,处理方法相同
while(!isEmpty(pSs)&&top(pSs)!='('){
char c=pop(pSs);
int temp=count(pSn,c);
push(pSn,temp);
}
push(pSs,str[i++]);
}else if(str[i]=='*'||str[i]=='/'){ //乘除法优先级大于加减号,比加减号优先计算
while(top(pSs)=='*'||top(pSs)=='/'){
char c=pop(pSs);
int temp=count(pSn,c);
push(pSn,temp);
}
push(pSs,str[i++]);
}else if(str[i]=='('){ //遇到左括号入栈,提升后面所有符号优先级
push(pSs,str[i++]);
}else if(str[i]==')'){//遇到右括号舍弃,将符号栈内符号逐一出栈进行运算,直到遇到左括号
while(top(pSs)!='('){
char c=pop(pSs);
int temp=count(pSn,c);
push(pSn,temp);
}
pop(pSs);
i++;
}else if(str[i]>='0'&&str[i]<='9'){ //处理多位数数字,字符串转换为整形
int temp=0;
while(str[i]>='0'&&str[i]<='9'){
temp=temp*10+str[i++]-'0';
}
push(pSn,temp);
}
}
while(!isEmpty(pSs)){ //处理完字符串后,符号栈不空的话,逐一出栈进行运算
char c=pop(pSs);
push(pSn,count(pSn,c));
}
int res=top(pSn);
clear(pSn);
clear(pSs);
return res;
}
#ifndef STACK_H
#define STACK_H
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
typedef struct _node Node;
typedef Node Stack;
struct _node{
int value;
Node *next;
};
#endif
Stack *creat_stack();
bool isEmpty(Stack *S);
bool push(Stack *S,int value);
int pop(Stack *S);
int top(Stack *S);
int tosuffix(char *str,int len);
int count(Stack *S,char c);