您的位置:首页 > 编程语言

编程实现计算器

2016-07-29 00:00 183 查看

需求

编程实现计算器,当输入一个表达式时,可以得出计算结果。(实现加、减、乘、除、取余以及负号运算)

思路

1.维护两个栈,一个栈my_dig用于push数字,另一个栈my_op用于push运算符。栈中元素结构如下:

typedefstructtag_stack1{intdig_arr[1024];intdig_top;}DIG,*pDIG;typedefstructtag_stack2{charop_arr[1024];intop_top;}OP,*pOP;


2.遍历表达式字符串,当遇到数字时,将数字push到栈my_dig中,这个没有问题。对于运算符需要讨论:

1)如果运算符是右括号,则my_op需要一直弹栈计算,直到左括号出栈。

2)如果运算符不是右括号,则需判断当前运算符与栈顶运算符的优先级高低,如果当前运算符优先级高,则入栈;否则弹栈计算,直到当前运算符优先级低于栈顶运算符优先级为止,此时当前运算符入栈。

注意

需要区分负号与其他运算符。本代码处理负号的入栈时,将其替换成‘@’,以便区分其与减号。

1.减号与负号,两者优先级不同。

2.对于负号的计算,每次从数字栈中只取一个操作数,而对于其他运算符(包括减号)的计算,每次从数字栈中需要取两个操作数。

代码

/*************************************************************************>FileName:main.c>Author:KrisChou>Mail:zhoujx0219@163.com>CreatedTime:Wed10Sep201407:44:10PMCST************************************************************************/#include<stdio.h>#include<stdlib.h>#include<string.h>typedefstructtag_stack1{intdig_arr[1024];intdig_top;}DIG,*pDIG;typedefstructtag_stack2{charop_arr[1024];intop_top;}OP,*pOP;staticintis_ok[8][8]={//+-*/%(#@)
/*+*/0,0,0,0,0,1,1,0,/*-*/0,0,0,0,0,1,1,0,/***/1,1,0,0,0,1,1,0,/*/*/1,1,0,0,0,1,1,0,/*%*/1,1,0,0,0,1,1,0,/*(*/1,1,1,1,1,1,1,1,/*#*/0,0,0,0,0,0,0,0,/*@*/1,1,1,1,1,1,1,0};staticcharop_arr[9]={'+','-','*','/','%','(','#','@',')'};staticintfind_index(charop){intindex;for(index=0;index<9;index++){if(op==op_arr[index]){returnindex;}}return-1;}staticintis_myspace(charc){if(c==''||c=='\n'||c=='\t'||c=='\v'){return1;}else{return0;}}staticvoidtrim_space(char*str){intslow=-1;intfast=0;while(str[fast]!='\0'){if(!is_myspace(str[fast])){str[++slow]=str[fast];}fast++;}str[++slow]='\0';}staticintcalculate(charop,intleft,intright){switch(op){case('+'):returnleft+right;break;case('-'):returnleft-right;break;case('*'):returnleft*right;break;case('/'):returnleft/right;break;case('%'):returnleft%right;break;}}inthandler(char*str){OPmy_op;DIGmy_dig;memset(&my_op,0,sizeof(OP));memset(&my_dig,0,sizeof(DIG));//两个栈,栈顶元素均指向下一个要入栈的位置
my_op.op_arr[my_op.op_top++]='#';intresult=0;intindex=0;for(index=0;str[index]!='\0';index++){intnumb;if(find_index(str[index])>=0&&find_index(str[index]<=8))/*操作符*/{intleft,right;charstk_op;inttmp_result;if(str[index]==')'){while(my_op.op_arr[my_op.op_top-1]!='('){stk_op=my_op.op_arr[--my_op.op_top];right=my_dig.dig_arr[--my_dig.dig_top];if(stk_op=='@'){tmp_result=-right;}else{left=my_dig.dig_arr[--my_dig.dig_top];tmp_result=calculate(stk_op,left,right);}my_dig.dig_arr[my_dig.dig_top++]=tmp_result;//新操作数入栈
}my_op.op_top--;//'('也出栈
}else{if(//操作符为负号
str[index]=='-'&&((index>0&&find_index(str[index-1])>=0&&find_index(str[index-1])<=4)||(index>0&&str[index-1]=='(')||(index>0&&str[index-1]=='@')||(index==0))){str[index]='@';}while(1){stk_op=my_op.op_arr[my_op.op_top-1];if(is_ok[find_index(str[index])][find_index(stk_op)])//运算符可以进栈
{my_op.op_arr[my_op.op_top++]=str[index];break;}else{my_op.op_top--;right=my_dig.dig_arr[--my_dig.dig_top];if(stk_op=='@'){tmp_result=-right;}else{left=my_dig.dig_arr[--my_dig.dig_top];tmp_result=calculate(stk_op,left,right);}my_dig.dig_arr[my_dig.dig_top++]=tmp_result;//新操作数入栈
}}}}else/*操作数*/{numb=0;while(str[index]>='0'&&str[index]<='9'){numb=numb*10+str[index]-'0';index++;}my_dig.dig_arr[my_dig.dig_top++]=numb;index--;}}while(my_op.op_arr[my_op.op_top-1]!='#'){intstk_op=my_op.op_arr[--my_op.op_top];intright=my_dig.dig_arr[--my_dig.dig_top];inttmp_result;intleft;if(stk_op=='@'){tmp_result=-right;}else{left=my_dig.dig_arr[--my_dig.dig_top];tmp_result=calculate(stk_op,left,right);}my_dig.dig_arr[my_dig.dig_top++]=tmp_result;//新操作数入栈
}result=my_dig.dig_arr[--my_dig.dig_top];returnresult;}intmain(intargc,char*argv[]){intret;charstr[1024];while(fflush(stdin),memset(str,0,1024),fgets(str,1024,stdin)){trim_space(str);ret=handler(str);printf("theresultis%d\n",ret);}return0;}



                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: