// 描述:
计算简单的算术表达式
// 输入:算术表达式(只支持浮点数的加减乘除,表达式以#结尾)
//
输出:计算结果
#define STACK_FIRST_SIZE 100
#define stack_addment 10
#define MAX_SIZE_OF_EXPRESSION 100 //支持的表达式的最长的字符长度
#include <stdlib.h>
#include "stdio.h"
//定义一个符号栈的结构体
typedef struct
{
char
op[MAX_SIZE_OF_EXPRESSION];
int top;
}stack_op,*pstack_op;
//将符号栈清空
void clear_stack_op(pstack_op s){
s->top=-1;
}
//符号栈压栈
void push_op(pstack_op s,char c){
s->top++;
s->op[s->top]=c;
}
//弹出符号栈的栈顶元素
char pop_op(pstack_op s){
int
i=s->top;
s->top--;
return
s->op[i];
}
//得到符号栈的栈顶元素
char get_op_top(pstack_op s){
return
s->op[s->top];
}
//判断符号栈是否为空
int is_stack_op_empty(pstack_op s){
if(s->top==-1){
return
1;//符号栈为空
}else{
return
0;//符号栈非空
}
}
//定义一个栈,存放操作数
typedef struct
{
float
num[MAX_SIZE_OF_EXPRESSION];
int top;
}stack_num,*pstack_num;
//将操作数栈清空
void clear_stack_num(pstack_num s){
s->top=-1;
}
//操作数压栈
void push_num(pstack_num s,float num){
s->top++;
s->num[s->top]=num;
}
//弹出栈顶的操作数
float pop_num(pstack_num s){
int
i=s->top;
s->top--;
return
s->num[i];
}
//得到栈顶操作数
float get_num_top(pstack_num s){
return
s->num[s->top];
}
//判断操作数栈是否为空
int is_stack_num_empty(pstack_num s){
if(s->top==-1){
return
1;//栈为空
}else{
return
0;//栈非空
}
}
//判断是否为数字或小数点
int is_digit(char x){
if((x>='0'&&x<='9')||x=='.')
return 1;
return
0;
}
float Operate(float n1,float n2,char c_op)
{
float r;
switch(c_op)
{
case
'+': r=n1+n2;break;
case
'-': r=n1-n2;break;
case
'*': r=n1*n2;break;
case
'/': r=n1/n2;break;
}
return
r;
}
// 比较两个操作符的优先级
char Precede(char c1,char c2){
if(c1=='+')
{
if(c2=='+') return
'>';
else
if(c2=='-') return '>';
else
if(c2=='*') return '<';
else
if(c2=='/') return '<';
else
if(c2=='(') return '<';
else
if(c2==')') return '>';
else
return '>';
}
else if(c1=='-')
{
if(c2=='+') return
'>';
else
if(c2=='-') return '>';
else
if(c2=='*') return '<';
else
if(c2=='/') return '<';
else
if(c2=='(') return '<';
else
if(c2==')') return '>';
else
return '>';
}
else if(c1=='*')
{
if(c2=='+') return
'>';
else
if(c2=='-') return '>';
else
if(c2=='*') return '>';
else
if(c2=='/') return '>';
else
if(c2=='(') return '<';
else
if(c2==')') return '>';
else
return '>';
}
else if(c1=='/')
{
if(c2=='+') return
'>';
else
if(c2=='-') return '>';
else
if(c2=='*') return '>';
else
if(c2=='/') return '>';
else
if(c2=='(') return '<';
else
if(c2==')') return '>';
else
return '>';
}
else if(c1=='(')
{
if(c2=='+') return
'<';
else
if(c2=='-') return '<';
else
if(c2=='*') return '<';
else
if(c2=='/') return '<';
else
if(c2=='(') return '<';
else
return '=';
}
else if(c1==')')
{
if(c2=='+') return
'>';
else
if(c2=='-') return '>';
else
if(c2=='*') return '>';
else
if(c2=='/') return '>';
else
if(c2==')') return '>';
else
return '>';
}
else
{
if(c2=='+') return
'<';
else
if(c2=='-') return '<';
else
if(c2=='*') return '<';
else
if(c2=='/') return '<';
else
if(c2=='(') return '<';
else
return '=';
}
}
// 中缀表达式转后缀表达式
//
算法思路:中缀、后缀表达式中操作数的次序一致,故扫描到中缀表达式操作数时直接输出即可;对于运算符,视其优先级别,优先级高的运算符先输出(先运算);设一存放运算符的栈S,先将S置空,存入‘#’。另设中缀表达式已存入数组mid[n]
。依次扫描mid[n]中各分量mid[i]送 x :
//
若x=操作数,直接输出x;
//
若x=‘#’(结束符),依次输出栈S中运算符,转换结束;
//
若x=‘)’,反复退栈输出S中子表达式运算符,直到栈顶=‘(’,并退掉;
//
若x=运算符,反复退栈输出栈S中运算符,直到栈顶符<x。
// 注意:不同的操作数之间用空格格开
void Mid_Post(const char*
mid_expression,char* post_expression){
int i=1,j=0;
char x,ch_precede;
stack_op st_op;//符号栈
clear_stack_op(&st_op);//置空栈
push_op(&st_op,'#');
while(is_stack_op_empty(&st_op)==0){//符号栈非空
x=mid_expression[i];
if( is_digit(x)){
do{
post_expression[j++]=x;
i++;
x=mid_expression[i];
}while(is_digit(x));
post_expression[j++]='
';//数字之间用空格格开
}else if(x=='#'){
while(!is_stack_op_empty(&st_op)){//符号栈非空
post_expression[j++]=pop_op(&st_op);
}
}else if(x==')'){
while(get_op_top(&st_op)!='('){
post_expression[j++]=pop_op(&st_op);
}
pop_op(&st_op);//将"("弹出
i++;
}else if(x==' '){
//do nothing
}else{
while((ch_precede=Precede(get_op_top(&st_op),x))!='<'){
post_expression[j++]=pop_op(&st_op);
}
push_op(&st_op,x);
i++;
}
}
}
//
计算后缀表达式的值
//
算法思路:设操作数栈st_num,先将其置空,然后扫描后缀表达式中各分量送x;
// 若x=操作数,直接进栈;
//
若x=运算符:b=Pop(&st_num),a=Pop(&st_num),作a、b关于x的运算,结果再进栈;
// 若x=‘#’,算法结束,输出栈顶,即表达式结果。
float PostCount(const char * post_expression){
int
i=0,j=0;
char
x;
char
num_temp[MAX_SIZE_OF_EXPRESSION];//临时存放字符型的数字,用来转换成浮点数
float
y,result,a,b;
stack_num st_num;//存放操作数
clear_stack_num(&st_num);
while(post_expression[i]!='#'){
x=post_expression[i];
if(is_digit(x)){
do{
num_temp[j++]=x;
i++;
x=post_expression[i];
}while(x!=' ');
num_temp[j]='\0';
y=atof(&num_temp[0]);//转换成数值,进栈
push_num(&st_num,y);
j=0;
i++;
}else{
b=pop_num(&st_num);
a=pop_num(&st_num);//取两操作数
result=Operate(a,b,x);
push_num(&st_num,result);
i++;
}
}
if(!is_stack_num_empty(&st_num)){
return
get_num_top(&st_num);
}
}
int main()
{
//定义两个数组用来存放中缀和后缀表达式
char
mid_expression[MAX_SIZE_OF_EXPRESSION],post_expression[MAX_SIZE_OF_EXPRESSION];
char if_continue='y';//用来判断是否继续
char
ch_in;//用来存储读入的字符
float result=0.0;
int i=1;
while(if_continue=='y'||if_continue=='Y'){
mid_expression[0]='#';
printf("请输入表达式,以#号结束:\n");
fflush(stdin); //清空缓存区
while(ch_in=getchar()){
if(i<
MAX_SIZE_OF_EXPRESSION){
mid_expression[i++]=ch_in;
}else{
printf("输入的表达式超出范围,请输入长度小于%d的表达式\n",MAX_SIZE_OF_EXPRESSION);
system("pause");
return
-1;
}
if(ch_in=='#'){
break;
}
}
fflush(stdin); //清空缓存区
i=1;
Mid_Post(mid_expression,post_expression);
result=PostCount(post_expression);
printf("计算结果为:%f\n",result);
printf("要继续吗?Y/N:");
scanf("%c",&if_continue);
}
system("pause");
return 0;
}
加载中,请稍候......