C++实现算术四则运算
2013-11-11 20:11
246 查看
四则运算是指仅包含数字及‘+’ ‘-’ ‘*’ ‘/‘和括号’(‘ ’)‘的算式;
此题在2014小米笔试与2014美团笔试中均曾出现。
编程考虑:
首要的问题在于四则运算顺序的考虑,首先计算括号内的结果,而后计算乘法,最后计算加法。
数据结构:
这种四则运算的题目,最好的实现方法,是利用两个栈或者两个链表等类似结构,其中一个存储当前结果,一个存储当前优先级较高的结果运算后的结果。以此来获得整体的运算结果。
编程实现:
(1) 如利用双栈进行操作,首先将现有字符串依次压入栈A,当遇到括号时,将括号内的算式单独提出,递归调用,并将返回结果压入栈A;
(2) 此时栈A中即去除了括号,而后将栈A中的值依次弹出,如果为数字和加法均压入栈B,若出现乘号或出号,则由B中弹出第一个操作数,由A中弹出第二个操作数,两个相乘或相除后压入栈B,此时栈B中仅有加减法;
(3) 而后类似结果(2)将栈依次操作压入栈A;最后弹出A的栈顶元素即可。
需要处理的异常情况:
(1) 多重括号问题。比如 ((1+2)*3+4)/2
(2) 括号不匹配问题。比如 ((1+2)*3 或 1+2)*3等等
(3) 输入为空问题。
(4) 除数为0的问题。
(5) 异常输入问题,输入非数字及运算符号的其他符号的问题。
1.包含括号的代码如下:
2.后缀表达式下的四则运算结果
后缀表达式是指不包含括号,运算符放在两个运算对象的后面,所有的计算按运算符出现的顺序,严格从左向右进行(不再考虑运算符的优先规则,如:(2 + 1) * 3 , 即2 1 + 3 *;因而可以通过两个连续的操作数与位于其后的操作数相结合从而首先获得结合结果;类似上面的计算结果,可以有如下代码实现:类似的,也可以编写前缀表达式的输出结果。
此题在2014小米笔试与2014美团笔试中均曾出现。
编程考虑:
首要的问题在于四则运算顺序的考虑,首先计算括号内的结果,而后计算乘法,最后计算加法。
数据结构:
这种四则运算的题目,最好的实现方法,是利用两个栈或者两个链表等类似结构,其中一个存储当前结果,一个存储当前优先级较高的结果运算后的结果。以此来获得整体的运算结果。
编程实现:
(1) 如利用双栈进行操作,首先将现有字符串依次压入栈A,当遇到括号时,将括号内的算式单独提出,递归调用,并将返回结果压入栈A;
(2) 此时栈A中即去除了括号,而后将栈A中的值依次弹出,如果为数字和加法均压入栈B,若出现乘号或出号,则由B中弹出第一个操作数,由A中弹出第二个操作数,两个相乘或相除后压入栈B,此时栈B中仅有加减法;
(3) 而后类似结果(2)将栈依次操作压入栈A;最后弹出A的栈顶元素即可。
需要处理的异常情况:
(1) 多重括号问题。比如 ((1+2)*3+4)/2
(2) 括号不匹配问题。比如 ((1+2)*3 或 1+2)*3等等
(3) 输入为空问题。
(4) 除数为0的问题。
(5) 异常输入问题,输入非数字及运算符号的其他符号的问题。
1.包含括号的代码如下:
struct Nnode { float num; char c; }; float computestr(char *str) { int left=0,right=0; int len=strlen(str); int bracketNUM(0); stack<Nnode> s1; stack<Nnode> s2; int number=0; Nnode temp; for (int i=0;i<len;) { int original=i; while(i<len&&str[i]>='0'&&str[i]<='9') { number=number*10+str[i]-'0'; i++; } if (i!=original)//有数字且可能为0,将数字压入堆栈 { temp.num=number; temp.c=NULL; s1.push(temp); number=0; } if (i<len&&(str[i]=='+' || str[i]=='-'|| str[i]=='*'|| str[i]=='/'))//压入符号 { temp.c=str[i]; temp.num=NULL; s1.push(temp); i++; } if (i<len&&str[i]=='(')//if includes brackets { bracketNUM=1;//multi brackets left=i; int j=i+1; for (;j<=len;j++) { if (bracketNUM==0) //bracket matches { right=j-1; char *bracket=(char *)malloc((right-left)*sizeof(char)); int bracketLen=0; for (int k=left+1;k<right;k++) { bracket[bracketLen++]=str[k]; } bracket[bracketLen]='\0'; float ret = computestr(bracket);//将括号重新处理 temp.num = ret; temp.c = NULL; s1.push(temp); free(bracket); break; } if (str[j]==')') { bracketNUM--; } if (j==len&&bracketNUM!=0) { cout<<"bracket not matches"; return -1; break; } if (str[j]=='(')//多重括号 { bracketNUM++; } } i=j; } } while(!s1.empty())//首先计算乘除法 { Nnode ch=s1.top(); s1.pop(); if (ch.c!='*'&&ch.c!='/') { s2.push(ch); } else if(ch.c!='*'||ch.c!='/') { float v1=s1.top().num; float v2=s2.top().num; s1.pop(); s2.pop(); if (ch.c=='*') { temp.num=v1*v2; temp.c=NULL; s2.push(temp); } else if (ch.c=='/') { if (v2==0) { cout<<"除数为0"<<endl; return -1; break; } else { temp.num=v1/v2; temp.c=NULL; s2.push(temp); } } } } while (!s2.empty()) { Nnode ch=s2.top(); s2.pop(); if (ch.c!='+'&&ch.c!='-') { s1.push(ch); } else if(ch.c=='+'||ch.c=='-') { float v1=s2.top().num; float v2=s1.top().num; s1.pop(); s2.pop(); if (ch.c=='+') { temp.num=v1+v2; temp.c=NULL; s2.push(temp); } else if (ch.c=='-') { //-has changed twice temp.num=v2-v1; temp.c=NULL; s2.push(temp); } } } return s1.top().num; }
2.后缀表达式下的四则运算结果
后缀表达式是指不包含括号,运算符放在两个运算对象的后面,所有的计算按运算符出现的顺序,严格从左向右进行(不再考虑运算符的优先规则,如:(2 + 1) * 3 , 即2 1 + 3 *;因而可以通过两个连续的操作数与位于其后的操作数相结合从而首先获得结合结果;类似上面的计算结果,可以有如下代码实现:类似的,也可以编写前缀表达式的输出结果。
float computestrmid(char *str) { int len=strlen(str); stack<Nnode> s1; stack<Nnode> s2; int number=0; for (int i=0;i<len;) { if (str[i]==' ')//ignore the space { i++; continue; } int original=i; while(i<len&&str[i]>='0'&&str[i]<='9') { number=number*10+str[i]-'0'; i++; } if (i!=original)//有数字且可能为0,将数字压入堆栈 { Nnode numb; numb.num=number; numb.c=NULL; s1.push(numb); number=0; } if (i<len&&(str[i]=='+' || str[i]=='-'|| str[i]=='*'|| str[i]=='/'))//压入符号 { Nnode ch; ch.c=str[i]; ch.num=0; s1.push(ch); i++; } } int flagnum(0); while(!s1.empty()) { Nnode elem=s1.top(); s1.pop(); if (elem.c==NULL)//当前是数字 { s2.push(elem); flagnum++; } else//当前是符号 { if (flagnum>=2)//有两个操作数出现 { float num1=s2.top().num; s2.pop(); float num2=s2.top().num; s2.pop(); Nnode temp; if (elem.c=='+') { float result=num1+num2; temp.num=result; } else if (elem.c=='-') { float result=num1-num2; temp.num=result; } else if (elem.c=='*') { float result=num1*num2; temp.num=result; } else if (elem.c=='/') { float result=num1/num2; if (num2==0) { cout<<"除数为0"<<endl; return -1; break; } temp.num=result; } temp.c=NULL; s2.push(temp); flagnum--; } else { s2.push(elem); } } } return s2.top().num; }
相关文章推荐
- 用C++实现一元多项式的四则运算包括数据的文件导入与导出
- #C++实现先中缀转后缀的算术表达式计算
- 算术表达式的计算(基于逆波兰表达式)的c++实现
- c++实现一个小型算术表达式
- c++实现四则运算
- 简单算术表达式C++实现
- 堆栈的应用(2) 中缀算术表达式到后缀(逆波兰记法reverse polish notation)的转换及其计算 C++实现
- 堆栈的应用(2) 中缀算术表达式到后缀(逆波兰记法reverse polish notation)的转换及其计算 C++实现
- 第五篇——C++实现四则运算
- 逆波兰表达式实现四则运算(C++版)
- c++实现大数加减乘除四则运算
- C/C++基础-原码/反码/补码/位操作实现四则运算
- 用C++实现简单随机二元四则运算
- 栈实现带括号的浮点型四则运算C++
- C++实现大数的四则运算
- 数据结构之——用C++实现算术表达式求值
- C++简单计算器实现(四则运算加括号)
- C++实现高精度大整数(大数)的四则运算
- C/C++ 实现整数四则运算
- 多项式的加法和乘法算术运算的C++实现