每天一道算法题(26)——输入字符串表达式求值
来源:互联网 发布:钢结构制图软件 编辑:程序博客网 时间:2024/06/10 04:00
题目:
输入字符串,求输出的值。输入的均为整形,要求包含运算符
例如输入: "24*1 +(4+6)*2+ (4-3*2) *( 4+6-9+(11-3*4)*2 +2)* 10+ 20 -3* 2 *4 +2"
输出结果:20
要求:对于多余空格字符完好的鲁棒性,函数原型:void process(const char* input, int &output)
思想:
1. 首先,介绍基本数值运算(不包含括号运算符)算法。例如计算“13+7*2*1-15-2*8+2”。先定义三个变量,整形left,right分别表示左,右操作数,定义bool变量flag。遍历字符串,初始为true。设定字符串指针为*str。 基本算法为左操作数记录当前结果,右操作数更新新的操作数。这里涉及到对下一个操作符号的试探,则四者者的变动为:
分析:
(1)该算法不回溯,只一次性遍历一遍字符串
(2)左右操作数不同时更新。且每一步都更新二者之一。
(3)若当前操作符为乘法操作,继续更新右操作数。
(4)当前操作为加减操作,则根据flag记录的前一操作符(true为加,false为减),更新左操作数=左操作数(flag?+:-)右操作数
2.本算法是上一算法的改进。这里使用递归法,将括号表达式也看作一个操作数。若遇到括号表达式,使用函数找出括回的位置,去掉括前和括回符号,递归调用主函数process,优先计算出括号表达式字符串里面的计算值。其它操作与上叙算法相同。
代码:
(1)int getNum(const char* & input)。当判断出某个字符串开头为数字,则计算出该数字,并移动字符串的指针至数字表达式的下一位置
(2)int calculate(const char* & input)。当判断出某个字符串开头为‘(’。找出括回,递归调用运算字符串值计算主函数process,计算出括号里面表达式的值。同时涉及到更新指针至括号表达式的下一位置。
(3)int getValue(const char*& input)。获得下一个操作数的值,这个操作数可能是数值字符串,也可能是括号表达式
(4)int process(const char* start,const char* end)。重载函数,运算字符串值计算主函数process。
//获得当前字符串某个操作数的值并且移动节点指针指向下一个位置int getNum(const char* & input){if(input==NULL) return 0;int result=0;while('0'<=*input&&*input<='9'){result=10*result+*input-'0';input++;}return result;}int process(const char* start,const char* end);int calculate(const char* &start){//当遇到一个括号表达式时,通过递归法,获得当前括号内的值if(*start!='('||!start)return 0;int count1=0; int count2=0;int result=0;const char* p=start; while(*p){ if(*p=='(') count1++; else if(*p==')') count2++; if(count2==count1)//括前和括回的个数相等,即找到匹配的括回 break; p++;//获得括回的位置 } start++;p--;//去掉括号, result= process(start,p);//递归调用process获得括号里表达式字符串的值。 start=p+2;//,更新指针,指向括回的下一个位置 return result;}//获得表达式的值,可能是一个数值表达式,也可能是某个括号表达式int getValue(const char* &start){ if(!*start) return 0; while(*start==' ') start++; if(*start>='0'&&*start<='9')//某个数字return getNum(start);else if(*start=='(')//括号表达式,计算括号的值 return calculate(start);else return 0;}//输入需要计算字符串的首位指针int process(const char* start,const char* end){if(start>=end)return 0;int left,right;left=right=0;//左右操作数bool flag=true;//true表示+,false表示-while(start<=(end+1)){//遍历整个字符串if(*start=='('){right=getValue(start);//将括号表达式也作为一个独立的操作数获取}//当前操作符为‘+’,‘-’,则可以根据前一操作符的正负(flag标定)更新左操作数,并移动指针else if(*start=='+'){if(flag)left=left+right;elseleft=left-right;flag=true;start++;}else if(*start=='-'){if(flag)left=left+right;elseleft=left-right;flag=false;start++;}//当获得某个右操作数后,发现当前操作符为‘*’//则立即获得后一个操作数(有可能是一个括号表达式)并进行乘法运算,持续更新右操作数else if(*start=='*'){start++;right=right*getValue(start);//继续计算右操作数,因为乘法的优先级较大}//指针指向某个数字,直接获取当前数字,并且更新右操作数else if(*start>='0'&&*start<='9')right=getValue(start);else if(start==end+1){//已经计算到字符串末尾,最后一次计算结果if(flag)left=left+right;elseleft=left-right;start++;} else start++;//中间的空格,略过}return left;}//函数原型void process(const char* input, int &output){if(!input)output=0;output=process(input,input+strlen(input)-1);//重载函数}
由于在主函数和右操作数获取函数均包含了空格字符检测,因此本算法对于多余空格鲁棒。同时,对于空白字符也鲁棒。
点击链接 获得【红杏出墙】插件,翻墙上网无压力!谷歌搜索无压力!
- 每天一道算法题(26)——输入字符串表达式求值
- 每天一道算法题——每天一道算法题
- 每天一道算法题——字符串匹配
- 每天一道算法题——汉诺塔
- 每天一道算法题——
- 每天一道算法题(21)——字符串的全排列和组合算法
- 输入一个表达式字符串求值
- 每天一道算法题(7)——在字符串中删除特定的字符
- 每天一道算法题(25)——字符串中连续出现次数最多的子串
- 每天一道算法题(29)——检测字符串的是否由移位得到
- 每天一道算法题(35)——删除字符串首尾的空格
- 【每天一道算法题】
- 【每天一道算法题】
- 【每天一道算法题】
- 每天一道算法题(16)——翻转链表
- 每天一道算法题(22)——扑克牌的顺子
- 每天一道算法题(23)——约瑟夫环问题
- 每天一道算法题(31)——正数减法
- 我们也会常常在生活中错过太多的昨天。
- WPF combobox 获取高亮项
- 浅谈Vivado HLS存储结构中Line Buffer
- 什么叫编译时和运行时
- MathType中真子集的输入技巧
- 每天一道算法题(26)——输入字符串表达式求值
- String,StringBuffer,StringBuild的区别
- 拥有主消息循环的worker线程
- nexus管理maven部署
- 会场安排问题
- JS正则表达式验证数字非常全
- 黑马程序员——java中数组的定义与应用
- unity3d ppsspp模拟器中的post processing shader在unity中使用
- 除了喜怒哀乐外还有许多的感情我们难以用语言文字表述