【栈】实现高级计算器
来源:互联网 发布:telnet 端口发送数据 编辑:程序博客网 时间:2024/05/19 11:46
实现一个计算器
9+2*8-2
30+2*6-1
7*2-3*5-2
实现思路:
1、程序扫描表达式
2、发现是数字就入数字栈(这里要特别注意,当数字不是一位的情况)
3.如果发现是运算符
a)如果符号栈为空,就直接入符号栈
b)如何符号栈,不为空,就判断
I) 如果当前运算符的优先级小于等于符号栈顶的这个运算符的优先级,就计算,并把计算结果入数栈.然后把当前符号入栈
这里要特别注意比如13-11-2的例子!当两个减号优先级相同时,如果不把已有的减号计算,就会计算成先计算11-2再用13-9=4的错误答案。所以这个地方是个while循环。
II) 如果当前运算符的优先级大于符号栈顶的这个运算符的优先级,就入栈.
4、最后把所有的数都出栈,计算,留在数栈中的值就是最后结果
<html><head><meta http-equiv='content-type' content='text/html;charset=gbk'/></head><?php//$exp=$_GET['exp'];//$exp='9+2*8-3'; //[人眼睛3+12-2 =>15-2=>13]// $exp='304+10*6-10'; $exp='71*2-50*3-3-67*6+80';//-333 $numsStack=new MyStack();$operStack=new MyStack();$keepNum='';//专门用于拼接数字$index=0;//$index就是一个扫描标记while(true){//依次取出字符$ch=substr($exp,$index,1);//判断$ch是不是一个运算符if($operStack->isOper($ch)==TRUE){//是运算符/***/if($operStack->isEmpty()){$operStack->push($ch);}else{/*//需要一个函数来获取运算符的优先级 *和/的优先级为1 ,+和-为0$chPRI=$operStack->PRI($ch);$stackPRI=$operStack->PRI($operStack->getTop());if($chPRI<=$stackPRI){//从数栈依次出栈两个数$num1=$numsStack->pop();$num2=$numsStack->pop();//再从符号栈取出一个运算符$oper=$operStack->pop();//这里还需要一个计算的函数$res=$operStack->getResult($num1,$num2,$oper);//把$res入数栈$numsStack->push($res);//把当前这个符号再入符号栈 ?????这里是有问题的,一会儿再来解决$operStack->push($ch);}else{$operStack->push($ch);}*/while(!$operStack->isEmpty()&&$operStack->PRI($ch)<=$operStack->PRI($operStack->getTop())){//从数栈依次出栈两个数$num1=$numsStack->pop();$num2=$numsStack->pop();//再从符号栈取出一个运算符$oper=$operStack->pop();//这里还需要一个计算的函数$res=$operStack->getResult($num1,$num2,$oper);//把$res入数栈$numsStack->push($res);//把当前这个符号再入符号栈 ?????这里是有问题的,一会儿再来解决}$operStack->push($ch);}}else{//是数字$keepNum.=$ch;//先判断是否已经到了字符串的最后,如果已经到最后了,就直接入栈//判断一下$ch字符的下一个字符是数字还是符号if($index==strlen($exp)-1){$numsStack->push($keepNum);}else{if($operStack->isOper(substr($exp,$index+1,1))){$numsStack->push($keepNum);$keepNum='';}}}$index++;//让index指向下一个字符//判断是否已经扫描完毕if($index==strlen($exp)){break;}//当扫描完毕后就break;}//只要符号栈不空就一直计算while(!$operStack->isEmpty()){$num1=$numsStack->pop();$num2=$numsStack->pop();$oper=$operStack->pop();$res=$operStack->getResult($num1,$num2,$oper);$numsStack->push($res);}//当退出while后,一定有一个数,这个数就是最终结果echo $exp.'='.$numsStack->getTop();//自定义的栈class MyStack{private $top=-1;//默认是-1,表示该栈是空的private $maxSize=5;//$maxSize表示栈的最大容量private $stack=array();//计算的函数public function getResult($num1,$num2,$oper){$res=0;switch($oper){case '+':$res=$num1+$num2;break;case '-':$res=$num2-$num1;break;case '*':$res=$num1*$num2;break;case '/':$res=$num2/$num1;break;}return $res;}//返回栈顶的字符,只是取出不出栈public function getTop(){return $this->stack[$this->top];}//判断优先级的函数public function PRI($ch){if($ch=='*'||$ch=='/'){return 1;}else if($ch=='+'||$ch=='-'){return 0;}}//判断栈是否为空public function isEmpty(){if($this->top==-1){return TRUE;}else{return FALSE;}}//增加一个函数【提示:在我们开发中,根据需要可以灵活增加需要的函数】//判断是不是一个运算符public function isOper($ch){if($ch=='-'||$ch=='+'||$ch=='*'||$ch=='/'){return TRUE;}else{return FALSE;}}//注意类里面的变量一定要用$this->xxx,不然就杯具了//入栈的操作public function push($val){//先判断栈是否已经满了if($this->top==$this->maxSize-1){echo '<br/>栈满,不能添加';return;}$this->top++;$this->stack[$this->top]=$val;}//显示栈的所有数据的方法public function showStack(){if($this->top==-1){echo '<br/>栈空';return;}echo '<br/>当前栈的情况是......';for($i=$this->top;$i>-1;$i--){echo '<br/>stack['.$i.']='.$this->stack[$i];}}//出栈的操作,就是把栈顶取出public function pop(){//判断是否是栈空if($this->top==-1){ echo '<br/>栈空';return;}//把栈顶的值,取出$topVal=$this->stack[$this->top];$this->top--;return $topVal;}}?></html>
- 【栈】实现高级计算器
- java高级计算器的实现
- JavaScript实现高级科学计算器库
- php利用堆栈 实现高级计算器
- 栈实现计算器
- 用栈实现计算器
- 用栈实现计算器
- 计算器(栈实现)
- 栈实现计算器
- 栈实现计算器
- 双栈实现计算器
- 栈实现计算器
- 编译原理:实现高级表达式计算器(初级)
- 高级电子计算器
- 高级计算器ASP.NET
- Android高级计算器
- 栈实现的简单计算器
- 栈实现计算器简单功能
- 内存管理与检测
- Remove Duplicates from Sorted List
- 关于button
- 基于visual Studio2013解决C语言竞赛题之1053洗牌
- notepad++ 正则表达式
- 【栈】实现高级计算器
- rmmod: chdir(/lib/modules): No such file or directory 解决方法
- Openstack之Cinder服务初探
- fusioncharts 入门系列1
- 我自己的关灯游戏代码
- JavaIO —— java.io.File类
- EF5.X Code First表关联与延迟加载
- WebService原理
- 网页在不同浏览器下的兼容问题--针对IE