表达式问题-C

表达式转后缀表达式: 

#include<stdio.h>
#include<stdlib.h>
#include<ctype.h> 
#include<assert.h>
#define INITSIZE  20
#define INCREMENT 10
#define MAXBUFFER 20
#define LEN  sizeof(Elemtype)
/*栈的动态分配存储结构*/ 
typedef char Elemtype;
typedef struct{
	Elemtype *base;
	Elemtype *top;
	int StackSize;
}SqStack;

/*初始化栈*/
void InitStack(SqStack *S) {
	S->base=(Elemtype*)malloc(LEN*INITSIZE);
	assert(S->base !=NULL);
	S->top=S->base;
	S->StackSize=INITSIZE;
}

/*压栈操作*/ 
void PushStack(SqStack *S,Elemtype c) {
	if(S->top - S->base >= S->StackSize) {
		S->base=(Elemtype*)realloc(S->base,LEN*(S->StackSize+INCREMENT));
		assert(S->base !=NULL);
		S->top =S->base+S->StackSize;
		S->StackSize+=INCREMENT;
	}
	*S->top++ = c;
}
/*求栈长*/
int StackLength(SqStack *S) {
	return (S->top - S->base);
}
/*弹栈操作*/
int PopStack(SqStack *S,Elemtype *c) {
	if(!StackLength(S)) {
		return 0;
	}
	*c=*--S->top;
	return 1;
}

/*中缀转后缀函数*/
void Change(SqStack *S,Elemtype str[]) {
	int i=0;
	Elemtype e;
	InitStack(S);
	while(str[i]!='\0') {
		while(isdigit(str[i])) {
			/*过滤数字字符,直接输出,直到下一位不是数字字符打印空格跳出循环 */
			printf("%c",str[i++]);
			if(!isdigit(str[i])) {
				printf(" ");
			}
		}
		if(str[i]=='+'||str[i]=='-') {
			if(!StackLength(S)) {
				PushStack(S,str[i]);
			} else {
				do {
					PopStack(S,&e);
					if(e=='(')
					{
						PushStack(S,e);
					} else {
						printf("%c ",e);
					}
				} while( StackLength(S) && e != '(' ); 
				PushStack(S,str[i]);
			}
		}
		/*当遇到右括号是,把括号里剩余的运算符弹出,直到匹配到左括号为止
		左括号只弹出不打印(右括号也不压栈)*/
		else if(str[i]==')') {
			PopStack(S,&e);
			while(e!='(') {
				printf("%c ",e);
				PopStack(S,&e);
			}
		} else if(str[i]=='*'||str[i]=='/'||str[i]=='(') {
			/*乘、除、左括号都是优先级高的,直接压栈*/
			PushStack(S,str[i]);
		} else if(str[i]=='\0') {
			break;
		} else {
			printf("\n输入格式错误!\n");
			return ;
		}
		i++;
	}
	/*最后把栈中剩余的运算符依次弹栈打印*/
	while(StackLength(S)) {
		PopStack(S,&e);
		printf("%c ",e);
	}
}
int main() {
	printf("请输入表达式,如:(2+(((2+6)*6+2)*2+6)*2):\n\n"); 
	Elemtype str[MAXBUFFER];
	SqStack S;
	gets(str);
	printf("\n转化为后缀表达式:");
	Change(&S,str);
	return 0;
}

 后缀表达式的计算:

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<ctype.h>
#define INITSIZE  20
#define INCREMENT 10
#define MAXBUFFER 10
#define LEN   sizeof(Elemtype)
/*栈的动态分配顺序存储结构*/
typedef double Elemtype;

//结构体 
typedef struct{
	Elemtype *base;
	Elemtype *top;
	int StackSize; 
}SqStack;
//初始化栈 
void InitStack(SqStack *S) {
	S->base=(Elemtype*)malloc(LEN*INITSIZE);
	assert(S->base != NULL);
	S->top=S->base;
	S->StackSize=INITSIZE;
}
//压栈 
void PushStack(SqStack *S,Elemtype e) {
	if(S->top - S->base >= S->StackSize)
	{
		S->base=(Elemtype*)realloc(S->base,(S->StackSize+INCREMENT)*LEN);
		assert(S->base !=NULL);
		S->top=S->base+S->StackSize;
		S->StackSize+=INCREMENT;
	}
	*S->top =e;
	 S->top++;
} 
//出栈 
void PopStack(SqStack *S,Elemtype *e) {
	*e=*--S->top;
} 
//计算-关键函数 
void CalFunction(SqStack *S,char str[]) {
	Elemtype number,e,d;
	char arr[MAXBUFFER];
	int i=0,j=0; 
	InitStack(S);
	while(str[i]!='\0') {
		while(isdigit(str[i])||str[i]=='.') { //过滤数字
			arr[j++]=str[i++];
			arr[j]='\0';
			if( j >= MAXBUFFER ) {
				printf("输入单个数据过大!\n");
				return ;
			}
			if(str[i]==' ') {
				number=atof(arr);    //利用atof函数将数字字符转化为double型数据
				PushStack(S,number); //将转换的数进行压栈
				j=0;
				break;
			}
		}
		switch(str[i]) {
			case '+':
				PopStack(S,&e);
				PopStack(S,&d);
				PushStack(S,d+e);
				break;
			case '-':
				PopStack(S,&e);
				PopStack(S,&d);
				PushStack(S,d-e);
				break;
			case '*':
				PopStack(S,&e);
				PopStack(S,&d);
				PushStack(S,d*e);
				break;
			case '/':
				PopStack(S,&e);
				PopStack(S,&d);
				if(e == 0) {
					printf("输入出错,分母为零!\n");
					return ;
				}
				PushStack(S,d/e);
				break;
		}
		i++; 	
	}
	PopStack(S,&e);
	printf("计算结果为:%lf",e);	
}
//主函数 
int main() {
	char str[100];
	SqStack S;
	printf("请按逆波兰表达式输入数据,每个数据之间用空格隔开,如:2 2 6 + 6 * 2 + 2 * 6 + 2 * + \n");
	gets(str);
	CalFunction(&S,str);
	printf("\n\n");
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值