C语言表达式求值-用栈实现

说明

本程序支持括号以及小数计算


基本思想

先将中缀表达式转换为后缀表达式,再求值
中缀转后缀可以借鉴该博文
表达式求值可以借鉴该博文


我的代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define maxsize 100
#define N 7
typedef struct{//运算符栈
	char data[maxsize];
	int top;
}seqOperate;

typedef struct{//运算数栈
	double data[maxsize];
	int top;
}seqData;

char operators[maxsize] = { '+', '-', '*', '/','=','(',')'};

int priotiry(char ch){//运算符优先级
	switch(ch){
	case '+':
		return 1;
	case '-':
		return 1;
	case '*':
		return 2;
	case '/':
		return 2;
	case '(':
		return 0;
	case ')':
		return 0;
	default:return -1;
	}
}
//判断运算符栈是否为空
int isEmptyOp(seqOperate *s1){
	if(s1->top == -1)
		return 1;
	else
		return 0;
}

//从运算符栈中弹出一个运算符
char popo(seqOperate *s1){
	if(!isEmptyOp(s1)){
		char ch=s1->data[s1->top];
		s1->top--;
		return ch;
	}
	else
		return 'F';
}
//运算符入栈
void pusho(seqOperate *s1,char ch){
	s1->top++;
	s1->data[s1->top]=ch;
}
//获取栈顶元素
char getTopo(seqOperate *s1){
	return s1->data[s1->top];
}
//初始化运算符栈
void initSeqOperate(seqOperate *s1){
	//s1=(seqOperate*)malloc(sizeof(seqOperate));
	s1->top=-1;
}
//初始化运算数栈
void initSeqData(seqData *s2){
	s2->top=-1;
}
//运算数入栈
void pushd(seqData *s2,double d){
	s2->top++;
	s2->data[s2->top]=d;
}
double popd(seqData *s2){
	double d;
	d=s2->data[s2->top];
	s2->top--;
	return d;
}
//判断所给字符是否为运算符
int isOperate(char ch){
	int i;
	for (i = 0; i < N; i++)
	{
		if (operators[i] == ch)
		{
			return 1;
		}
	}
	return 0;
}
char * infixToAffix(char *str){
	seqOperate *s1;
	int i=0,j=0;
	char ch;
	static char result[maxsize];
	s1=(seqOperate*)malloc(sizeof(seqOperate));//在codeblocks和vc++6.0上都需要这一句,dev-c++上不需要,请视情况而定
//	char result[maxsize];
	initSeqOperate(s1);
	while(str[i]!='\0'){
		if(str[i]=='.'||(str[i]<='9'&&str[i]>='0')){
			result[j++]=str[i];
		}
		else{
			result[j++]='#';//将数字字符串和操作符分开--转换时定界的功能
			if(str[i]=='+'||str[i]=='-'){
				if(isEmptyOp(s1)){
					pusho(s1,str[i]);
				}
				else{
					while(getTopo(s1)!='('&&!isEmptyOp(s1)){
						ch=popo(s1);
						result[j++]=ch;
					}
					pusho(s1,str[i]);
				}
			}
			else if(str[i]==')'){
				ch=popo(s1);
				while(ch!='('){
					result[j++]=ch;
					ch=popo(s1);
				}
			}
			else if(str[i]=='*'||str[i]=='/'||str[i]=='('){
				pusho(s1,str[i]);
			}
		}
		i++;
	}
	while(!isEmptyOp(s1)){
		ch=popo(s1);
		result[j++]=ch;
	}
//	printf("-------\n");
//	printf("%s\n",result);
	return result;
}
double getAffixValue(char *res){
	seqData *s2;
	double sum,t,a,b,result;
	int i=0;
	s2=(seqData *)malloc(sizeof(seqData));
	initSeqData(s2);
	while(res[i]!='\0'){
		if(res[i]<='9'&&res[i]>='0'){
			sum=0;
			t=10;
			sum=res[i]-'0';
			i++;
			while((res[i]<='9'&&res[i]>='0')||res[i]=='.'){//字符串转double
				if(res[i]!='.'){
					if( t == 10)
						sum = sum * t + res[i] - 48;
					else
					{
						sum += ( res[i] - 48 ) * t;
						t = t*0.1;
					}
				}
				else{
					t=0.1;
				}
				i++;
			}
		//	printf("%lf %d\n",sum,i);
			pushd(s2,sum);

		}
		if(res[i]=='+'||res[i]=='-'||res[i]=='*'||res[i]=='/'){
			a=popd(s2);
			b=popd(s2);
			if(res[i]=='+')
				pushd(s2,b+a);
			if(res[i]=='-')
				pushd(s2,b-a);
			if(res[i]=='*')
				pushd(s2,b*a);
			if(res[i]=='/')
				pushd(s2,b/a);
		}
		i++;

	}
	result=popd(s2);
	//printf("最终结果为:%lf",result);
	return result;
}
int main(){
	int n,m;
	char * res;
	char str[maxsize];
	double result;
	scanf("%d",&n);
	while(n--){
		scanf("%s",str);
		res = infixToAffix(str);
		//printf("result%s\n",res);
		result=getAffixValue(res);
		m=(int)result;
		if(result-m==0)
			printf("%d\n",m);
		else
			printf("%.2lf\n",result);
	}
}

ps:欢迎评论指正

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值