后缀表达式及计算器

#include<stdio.h>
#include<stdlib.h>

#define MAX 100
typedef char datatype ;
//栈结构体
typedef struct 
{
	datatype a[MAX] ;
	int size ;

}sequence_stack ;

void init(sequence_stack *) ;
int empty(sequence_stack *) ;
datatype read(sequence_stack *) ;
void pop(sequence_stack *) ;
void push(sequence_stack *,datatype) ;
int is_operation(char ch) ;
int priority(char ch) ;
//中缀表达式转后缀表达式的函数
void postfix(char* ,char*) ;
double read_number(char *dest ,int *i) ;
double answer(char *dest) ;
void match(char *src) ;

/*
------------------------------
初始化函数
------------------------------
*/
void init(sequence_stack *s)
{
	if (!s){return;}
	s->size = 0 ;
}


/*
------------------------------
判断是否为空栈
------------------------------
*/
int empty(sequence_stack *s)
{
	if (!s){return 0;}
	return s->size ? 0:1 ;
}
/*
------------------------------
读取栈顶元素
------------------------------
*/
datatype read(sequence_stack *s)
{
	if(empty(s))
	{
		printf("read函数错误, 为空栈!!") ;
		exit(1) ;
	}
	return s->a[s->size-1] ;
}

void pop(sequence_stack *s)
{
	if(empty(s))
	{
		printf("pop函数错误, 为空栈!!") ;
		exit(1) ;
	}
	s->size-- ;
}

void push(sequence_stack *s ,datatype d)
{
	if(s->size==MAX)
	{
		printf("push函数错误, 栈已满!!") ;
		exit(1) ;
	}
	s->a[s->size++] = d  ;
}
/*
------------------------------
判断字符是否是操作符
------------------------------
*/
int is_operation(char ch)
{
	int f = 0 ;
	switch(ch)
	{
	case '+':
	case '-':
	case '*':
	case '/':
		f =1 ;
		break ;
	default:
		f =0 ;
		break ;
	}
	return f ;
}


/*
------------------------------
获得优先级
------------------------------
*/
int priority(char ch)
{
	int f =-1 ;
	switch(ch)
	{

	case '#':
		f = -1 ;
		break ;
	case '(':
	case ')':
		f = 0 ;
		break ;
	case '+':
	case '-':
		f = 1;
		break ;
	case '*':
	case '/':
		f =2 ;
		break ;
	default:
		break;
	}
	return f ;

}
/*
-----------------------------
中缀表达式转后缀表达式
src存储的是中缀表达式
dest存储的是后缀表达式
分为4个部分:
1.遇到数字字符怎么处理
	将数字读出
2.遇到运算字符的处理
	用while读取栈顶,栈顶元素>=运算符 ,就出栈,直到退出循环,最后将运算符压入栈中
3.遇到(的处理
	将(压入栈中即
4.遇到)的处理
	运算字符不用判断优先级全部出栈,直到遇到(与它配对
-----------------------------
*/
void postfix(char *src,char *dest)
{
	//创建栈结构体
	sequence_stack opt ;
	sequence_stack *p = &opt ;
	int i =0 ;
	int j =0 ;
	//一定要初始化栈
	init(p) ;
	push(p,'#') ;
	while(src[i]!='#')
	{
		
		if(src[i]>='0'&&src[i]<='9')
		{
			while( (src[i]>='0'&&src[i]<='9')||src[i]=='.' )
				dest[j++] = src[i++] ;
		}
		else if(is_operation(src[i]))
		{
			dest[j++] = ' ' ;
			while(priority(src[i]) <= priority( read(p) ))
			{
				dest[j++] = read(p) ;
				pop(p) ;
			}
			push(p,src[i]) ;
			i++ ;		
		}
		else if(src[i]=='(')
			push(p,src[i++]) ;
		else if(src[i]==')')
		{
			while(read(p)!='(')
			{
				dest[j++] = read(p) ;
				pop(p) ;
			}
			if(read(p)=='(')
				pop(p) ;
			i++ ;
		}
	
	}
	while(empty(p)!=1)
	{
		dest[j++] = read(p) ;
		pop(p) ;
	}
	dest[j] ='\0' ;

}
/*
-------------------------------
从后缀表达式中读取数据
-------------------------------
*/
double read_number(char *dest ,int *i)
{
	double x = 0 ;
	int num =0  ;
	int j ;
	while(dest[*i]<'0'||dest[*i]>'9') (*i)++;
	while(dest[*i]>='0'&&dest[*i]<='9')
	{
		x = x*10+(dest[*i]-'0') ;
		(*i)++ ;
	}
	
	if(dest[*i]=='.')
	{
		(*i)++ ;
		while(dest[*i]>='0'&&dest[*i]<='9')
		{
			num++ ;
			x = x*10+(dest[*i]-'0') ;
			(*i)++ ;
		}
	}
	for(j=0 ;j<num ;j++)
		x=x/10 ;

	return x ;
}


/*
---------------------------
根据后缀表达式计算结果
---------------------------
*/
double answer(char *dest)
{
	double xs[50] ;
	int len = 0 ;
	int i = 0 ;
	while(dest[i]!='#')
	{
		if(dest[i]>='0'&&dest[i]<='9')
			xs[len++] = read_number(dest,&i) ;
		else if(is_operation(dest[i]))
		{
			switch(dest[i])
			{

			case '+':
				xs[len-2] = xs[len-2]+xs[len-1] ;
				len-- ;
				i++ ;
				break ;
			case '-':
				xs[len-2] = xs[len-2]-xs[len-1] ;
				len-- ;
				i++ ;
				break ;
			case '*':
				xs[len-2] = xs[len-2]*xs[len-1] ;
				len-- ;
				i++ ;
				break ;
			case '/':
				xs[len-2] = xs[len-2]/xs[len-1] ;
				len-- ;
				i++ ;
				break ;

			}
		
		}
		else i++ ;
					
	}
	return xs[len-1] ;
	
}

/*
----------------------------
匹配表达式是否正确
----------------------------
*/
void match(char *src)
{
	int i =0 ;
	sequence_stack stack ;
	sequence_stack *p = &stack ;
	init(p) ;

	while(src[i]!='#')
	{
		//如果表达式中的不是下列字符
		if( (is_operation(src[i])!=1&&src[i]!='('&&src[i]!=')' &&src[i]!='.') && ( src[i]<'0'||src[i]>'9') )
		{
			printf("输入错误!!") ;
				exit(1) ;
		}
		switch(src[i])
		{
		case '(':
			push(p,src[i]) ;
			break ;
		case ')':
			if(is_operation(src[i-1])||src[i-1]=='(')
			{
				printf("括号输入有误!") ;
				exit(1) ;
			}
			if(read(p)=='(')
				pop(p) ;
			else
			{
				printf("括号输入有误!") ;
				exit(1) ;
			}
			
			break ;
		case '+':
		case '-':
		case '*':
		case '/':
			if(src[i-1]=='('||is_operation(src[i-1]))
			{
				printf("运算符输入问题!");
				exit(1) ;
			}
			break ;
		default:break ;
		}//switch

		i++ ;
	}
	

}

int main()
{
	char src[MAX] ;//中缀表达式
	char dest[MAX] ;//后缀表达式
	char ch ;
	int i =0 ;
	double n =0 ;
	while((ch=getchar())!='\n')
	{
		src[i++] = ch ;
	}
	src[i++] = '#' ;
	src[i] ='\0' ;
	printf("中缀表达式: %s\n",src) ;

	match(src) ;

	postfix(src,dest) ;
	printf("后缀表达式: %s\n",dest) ;

	n = answer(dest) ;
	printf("answer = %.2f\n",n) ;
	
	getchar() ;
	return 0 ;
}

发布了62 篇原创文章 · 获赞 28 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/native_lee/article/details/52452948