C语言 利用栈来表达式求值

这篇博客介绍了如何使用C语言编写程序,通过栈来处理中缀表达式,将其转换为后缀表达式并进行求值。程序首先检查输入的合法性,然后初始化两个栈,一个用于存储运算符,另一个用于存储数字。接着,根据运算符的优先级将运算符压栈,并计算后缀表达式。最后输出计算结果。

C语言——表达式求值,利用栈

输入含[ + , - , * , / , ( , ) ] 的一正确字符,利用栈来求值。先求出逆波兰表达式,再利用表达式来求值。话不多说,直接上代码:

#include<stdio.h>
#include<stdlib.h>
#define STACK_SIZE 50

typedef struct{//运算符栈,char型 
	char *base;//栈底指针 
	char *top;//栈顶指针 
	int stacksize;
}stack;

typedef struct{//数字栈,double型 
	double *base;//栈底指针 
	double *top;//栈顶指针 
	int stacksize;
}stack1;

typedef struct{
	char  *a[50];
	int num;
}Nibolan;

bool is_lawful(char a){//判断输入合法性 
	if(a!='+' && a!='-' && a!='*' && a!='/' && a!=')' && a!='('){
		if(a<48 || a>57){
			return false;
		}
	}
	return true;
}

int initStack(stack &stack){//初始化栈 
	stack.base = (char*)malloc(STACK_SIZE*sizeof(char));
	stack.top = stack.base;
	stack.stacksize = STACK_SIZE;
	return 0;
}

int initStack1(stack1 &stack){//初始化栈 
	stack.base = (double*)malloc(STACK_SIZE*sizeof(double));
	stack.top = stack.base;
	stack.stacksize = STACK_SIZE;
	return 0;
}

int initNipolan(Nibolan &ni){//初始化栈 
	ni.num = 50;
	for(int i=0;i<ni.num;i++){
		ni.a[i] = (char*)malloc(2*sizeof(char));
	}
	return 0;
}

int push(stack &stack,char a){//入运算符栈 
	if(stack.top-stack.base >= stack.stacksize){
		stack.base = (char*)realloc(stack.base,
		(stack.stacksize+STACK_SIZE) * sizeof (char) );
		stack.top = stack.base + stack.stacksize;
		stack.stacksize += STACK_SIZE;
	}
	*(stack.top) = a;
	stack.top++;
	return 0;
} 

int push1(stack1 &stack,double a){//入数字栈 
	if(stack.top-stack.base >= stack.stacksize){
		stack.base = (double*)realloc(stack.base,
		(stack.stacksize+STACK_SIZE) * sizeof (double) );
		stack.top = stack.base + stack.stacksize;
		stack.stacksize += STACK_SIZE;
	}
	*(stack.top) = a;
	stack.top++;
	return 0;
} 

bool is_number(char a){//判断输入是否为数字 
	if(a<48 || a>57){
		return false;
	}
	return true;
}

bool compare(char a1,char a2){//比较运算符大小,a1为要入栈元素,a2为栈顶元素,a1>a2时能入栈  
	if(a2=='#' || a2=='('){
		return true;
	}
	else if(a1=='('){
		return true;
	}
	else if( (a1=='*' ||a1=='/') && (a2=='+' || a2=='-') )
	{
		return true;
	}
	else{
		return false;
	}
}

int to_number(char a){//转换成数字 
	int x=0;
	x = (int)a-48;
	return x;
}

char pop(stack &s){//出栈 
	return *--s.top;
}

double pop1(stack1 &s){//出栈 
	return *--s.top;
}

char get_top(stack &s){//获取运算符栈栈顶元素 
	char S = *(s.top-1);
	return S;
}

double get_top1(stack1 &s){//获取数字栈栈顶元素 
	double S = *(s.top-1);
	return S;
}

double count(double x1,double x2,char c){//计算 ,x1-x2,x1/x2 
	double x;
	switch(c){
		case '-': x = x1-x2; break;
		case '+': x = x1+x2; break;
		case '*': x = x1*x2; break;
		default :x = x1/x2;
	}
	return x;
}

int input_(char *a){//输入函数 
	char a1;
	int num1=0;
	printf("请输入运算式(输入为整数且最多为三位数)\n");
	a1 = getchar();
	while(a1!='\n'){
		if(!is_lawful(a1)){
			printf("输入不合法");	
			exit(0);
			break;
		}
		a[num1] = a1;
		a1 = getchar();
		num1++;
	}
	return num1;
} 


int handle(int num,char *a,stack &s,stack1 &s1,Nibolan &ni){
	int i,n = 0;
	double x;
	push(s,'#');
	printf("后缀表达式为:\n"); 
	for(i=0;i<num;i++){
		if(is_number(a[i])){//是数字,入栈 
			int count = (int)to_number(a[i]);
			if(is_number(a[i+1])){//判断是否为三位数 
					count = count*10;
					count+=to_number(a[i+1]);
					i++;
					if(is_number(a[i+1])){
						count = count*10;
						count+=to_number(a[i+1]);
						i++;
					} 
			}
			x = (double)count;
			itoa(count,ni.a[n],10);
			printf("%s ",ni.a[n]);
			n++;
			push1(s1,x);
		}
		else{//判断运算符情况
			if(a[i]==')'){
				while(get_top(s)!='('){
					char c = pop(s);
					char Q[2];
					Q[0] = c;
					Q[1] = '\0';
					ni.a[n] = Q;
					printf("%s ",ni.a[n]);
					n++;
					double x1 = pop1(s1);
					double x2 = pop1(s1);
					double P = count(x2,x1,c);
					push1(s1,P);
				}
				char Q = pop(s);
			}
			else{
				while(!compare(a[i],get_top(s))){
					char c = pop(s);
					char Q[2];
					Q[0] = c;
					Q[1] = '\0';
					ni.a[n] = Q;
					printf("%s ",ni.a[n]);
					n++;
					double x1 = pop1(s1);
					double x2 = pop1(s1);
					double P = count(x2,x1,c);
					push1(s1,P);
				}
				push(s,a[i]);
			}
		}		
	}
	while(s.top-s.base!=1){
		char c = pop(s);
		char Q[2];
		Q[0] = c;
		Q[1] = '\0';
		ni.a[n] = Q;
		printf("%s ",ni.a[n]);
		n++;
		double x1 = pop1(s1);
		double x2 = pop1(s1);
		double P = count(x2,x1,c);
		push1(s1,P);
	}
	printf("\n");
	return 0;
}

int output(int num,char *a,stack1 s1,Nibolan ni){//输出结果 
	int i=0;
	printf("\n");
	for(i=0;i<num;i++){
		printf("%c",a[i]);
	}
	printf(" = %.2f",get_top1(s1));
}

int main(){
	stack s;//运算符栈 
	stack1 s1;//数字栈 
	initStack(s);
	initStack1(s1);
	char a[50];
	Nibolan ni;
	initNipolan(ni);
	int num = input_(a);
	handle(num,a,s,s1,ni);
	output(num,a,s1,ni);
	return 0;
} 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值