编程实现计算器
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;}
相关文章推荐
- 我的C++实践(16):引用计数实现
- Java集合框架官方教程(1):Collection/Set/List接口
- Java并发与多线程教程(1)
- 我的C++实践(14):限制类对象的个数
- Python之禅
- Java集合框架官方教程(3):SortedSet/SortedMap接口
- 我的C++实践(10):智能指针
- C++ Primer学习系列(4):关联容器/泛型算法/类
- C++ Primer学习系列(3):函数/标准IO库/顺序容器
- 高吞吐低延迟Java应用的垃圾回收优化
- Java并发与多线程教程(3)
- 深入理解Java类加载器(1):Java类加载原理解析
- 浅析Java虚拟机结构与机制
- 深入理解Java注解(2):高级应用
- Java集合框架官方教程(6):算法
- 深入理解Java国际化
- 我的C++实践(7):模板元编程实战
- SQLite剖析(3):C/C++接口介绍
- 我的C++实践(14):限制类对象的个数
- Python之禅