简单计算器(栈的应用)

主要思路是,将读取的中缀运算式转换为后缀运算式。分别设置一个数字栈和一个符号栈,边读取边处理。处理办法为:

1、读取到加减号时,将栈内高于或等于加减号优先级的符号逐一出栈进行运算,当前符号入栈。

2、读取到乘除号时,将栈内高于或等于乘除号优先级的符号逐一出栈进行运算,当前符号入栈。

3、读取到左括号时,直接入栈,正常进行下面的读取。

4、读取到右括号时,舍弃;将栈内符号逐一出栈进行运算,直到左括号出栈后舍弃。

5、读取完运算式后,符号栈不一定为空,需要逐一出栈运算。

代码如下:

#include 
#include 
#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 
#include 
#include 
#include 
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);

你可能感兴趣的:(算法,数据结构)