多项式运算

/*
多项式运算
顺序栈实现
在demo1.cpp基础上增加 弥补异常处理 以及多位数运算缺点
*/
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>

#define OK 1
#define ERROR 2
#define OVERFLOW -1
#define INI_SIZE 100
#define APPEND 10

typedef int Elemtype_int;
typedef char Elemtype_char;
typedef int statue;
typedef struct{
	Elemtype_int *pTop_int;
	Elemtype_int *pBottom_int;
	int stack_int_size;	
}stack_int;
typedef struct{
	Elemtype_char *pTop_char;
	Elemtype_char *pBottom_char;
	int stack_char_size;
}stack_char;
statue ini_int(stack_int *stack){//初始化
	stack->pBottom_int=(Elemtype_int *)malloc(sizeof(Elemtype_int)*INI_SIZE);
	if(stack->pBottom_int==NULL){
		printf("内存分配失败\n");
		exit(OVERFLOW);
	}
	stack->pTop_int=stack->pBottom_int;
	stack->stack_int_size=INI_SIZE;
return OK;
}
statue ini_char(stack_char *stack){//初始化
	stack->pBottom_char=(Elemtype_char *)malloc(sizeof(Elemtype_char)*INI_SIZE);
	if(stack->pBottom_char==NULL){
		printf("内存分配失败\n");
		exit(OVERFLOW);
	}
	stack->pTop_char=stack->pBottom_char;
	stack->stack_char_size=INI_SIZE;
return OK;
}
statue push_int(stack_int *stack,int val){//入栈
	if(stack->pTop_int-stack->pBottom_int==stack->stack_int_size){
		stack->pBottom_int=(Elemtype_int *)realloc(stack->pBottom_int,stack->stack_int_size+sizeof(Elemtype_int)*APPEND);
		if(stack->pBottom_int==NULL){
			printf("内存分配失败\n");
			exit(OVERFLOW);
		}
		stack->pTop_int=stack->pBottom_int+stack->stack_int_size;
		stack->stack_int_size+=APPEND;
	}
	*stack->pTop_int=val;
	stack->pTop_int++;
return OK;
}
statue push_char(stack_char *stack,char val){//入栈
	if(stack->pTop_char-stack->pBottom_char==stack->stack_char_size){
		stack->pBottom_char=(Elemtype_char *)realloc(stack->pBottom_char,stack->stack_char_size+sizeof(Elemtype_char)*APPEND);
		if(stack->pBottom_char==NULL){
			printf("内存分配失败\n");
			exit(OVERFLOW);
		}
		stack->pTop_char=stack->pBottom_char+stack->stack_char_size;
		stack->stack_char_size+=APPEND;
	}
	*stack->pTop_char=val;
	stack->pTop_char++;
return OK;
}
statue pop_int(stack_int *stack,int *val){//出栈
	if(stack->pBottom_int==stack->pTop_int){
		printf("栈为空\n");
		return ERROR;
	}
	stack->pTop_int--;
	*val=*stack->pTop_int;
return OK;
}
statue pop_char(stack_char *stack,char *val){//出栈
	if(stack->pBottom_char==stack->pTop_char){
		printf("栈为空\n");
		return ERROR;
	}
	stack->pTop_char--;
	*val=*stack->pTop_char;
return OK;
}
bool In(char val){//判断是否为运算符
	if(val>='0'&&val<='9'){			
		return true;
	}else{
		return false;
	}
}
char getTOP(stack_char stack){
	char *p=stack.pTop_char;
	p=p-1;
	return *p;
}
char precade(char a,char b){
	int i,j;
	char pre[][7]={           
        {'>','>','<','<','<','>','>'},  
        {'>','>','<','<','<','>','>'},  
        {'>','>','>','>','<','>','>'},  
        {'>','>','>','>','<','>','>'},  
        {'<','<','<','<','<','=','0'},  
        {'>','>','>','>','0','>','>'},  
        {'<','<','<','<','<','0','='}};  
		switch(a){
		case '+':
			i=0;
			break;
		case '-':
			i=1;
			break;
		case '*':
			i=2;
			break;
		case '/':
			i=3;
			break;
		case '(':
			i=4;
			break;
		case ')':
			i=5;
			break;
		case '#':
			i=6;
			break;
		
		}
		switch(b){
		case '+':
			j=0;
			break;
		case '-':
			j=1;
			break;
		case '*':
			j=2;
			break;
		case '/':
			j=3;
			break;
		case '(':
			j=4;
			break;
		case ')':
			j=5;
			break;
		case '#':
			j=6;
			break;
		
		}
		return pre[i][j];

}
int operate(int a,char val,int b){
	printf("----%d%c%d---\n",a,val,b);
	switch(val){
	case'+':
		return a+b;
	case'-':
		return a-b;
	case'*':
		return a*b;
	case'/':
		return a/b;
	}
}
void show(stack_int stack){
	Elemtype_int *p=stack.pTop_int-1;
	while(p!=stack.pBottom_int-1){
		printf("%d    ",*p);
		p--;
	}
	printf("\n");
}
void run(char *val){
	char *p=val;
	stack_int s_int;
	stack_char s_char;
	int reslute;
	ini_int(&s_int);
	ini_char(&s_char);
	push_char(&s_char,*val);
	*val++;//先将#入栈	
	while(true){
		printf("%c\n",*val);
		if(In(*val)){//是数字
			push_int(&s_int,(*val-48));
		}else{//是字符
			char flog=precade(getTOP(s_char),*val);
			switch(flog){
			case'<':
				push_char(&s_char,*val);
				break;
			case'>':
				int a,b,myval;
				char poer;
				show(s_int);//
				pop_int(&s_int,&a);
				pop_int(&s_int,&b);
				pop_char(&s_char,&poer);
				myval=operate(b,poer,a);
				push_int(&s_int,myval);
				val--;
				break;
			case'=':
				char p;
				pop_char(&s_char,&p);
				break;
			}
		}
		if(*val=='#'){
			break;
		}
		val++;
	}
	
	reslute=*(s_int.pTop_int-1);
	show(s_int);
	printf("结果:%d\n",reslute);
}
bool isChar(char val){//判断是否为 + - * /
	if(val=='+'||val=='-'||val=='*'||val=='/'){
		return true;
	}
	return false;
}
bool isKuo(char q){
	if(q=='('||q=='<'||q=='{'||q=='['||q==')'||q=='>'||q=='}'||q==']'){
		return true;
	}
	return false;
}
bool isEmpty(stack_char stack){//判断是否为空
	if(stack.pTop_char==stack.pBottom_char){
		return true;
	}
	return false;
}
bool judge(char *val){//检查表达式格式
	char *p=val,*q=val;
	stack_char stack;//存储括号
	ini_char(&stack);
	//必须以#开头
	if(*p!='#'){
		printf("ERROR\n");
		return false;
	}
	p++;
	//#后面必须为数字
	if(!In(*p)){
		printf("ERROR\n");
		return false;
	}
	//满足以上条件后开始遍历
	while(*val){
		if(!In(*val)){
			//如果含有其它字符会报错
			if(*val=='+'||*val=='-'||*val=='*'||*val=='/'||*val=='('||*val==')'||*val=='#'){
			}else{
				return false;
			}
		}
		if(isChar(*val)){
			*val++;
			if(isChar(*val)){
				val--;
				printf("ERROR++\n");
				return false;
			}
		}
		val++;
	}
	val--;
	if(*val!='#'){//必须以#结尾
		printf("ERROR\n");
		return false;
	}
	//判断括号是否合法
	while(*q){
		if(isKuo(*q)){
			if(*q=='('||*q=='<'||*q=='{'||*q=='['){
				//入栈
				push_char(&stack,*q);
				q++;
			}else{
				if(isEmpty(stack)){
					printf("括号1不合法\n");
					return false;
				}
				if(*q==')'&&*(stack.pTop_char-1)=='('||*q=='>'&&*(stack.pTop_char-1)=='<'||*q=='}'&&*(stack.pTop_char-1)=='{'||*q==']'&&*(stack.pTop_char-1)=='['){
					//出栈
					char myval;
					pop_char(&stack,&myval);
					q++;
				}else{
					printf("括号2不合法\n");
					return false;
				}
			}
		}else{
			q++;
		}
	}
		
	if(isEmpty(stack)){
		return true;
	}
	return true;
}
int main(void){
	char asd[100],*p;
	p=asd;
	printf("请输入表达式 #开头结尾\n");
	gets(asd);
	if(judge(p)){
		run(p);
	}else{
		printf("格式错误\n");
	}
return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值