#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 ;
}
后缀表达式及计算器
最新推荐文章于 2022-12-27 22:01:14 发布