• PHP 算法之 -- 计算器设计


    <?php//$exp='300+20*6-20'; 
        $exp='71*2-50*3-3-67*6+80'; //14-15-3=-4
        //定义一个数栈和一个符号栈
        $numsStack=new MyStack();
        $operStack=new MyStack();
        $keepNum='';//专门用于拼接多位数的字符串
        $index=0;//$index就是一个扫描的标记
        while(true){
                //依次取出字符
                $ch=substr($exp,$index,1);
                //判断$ch是不是一个运算符号.
                if($operStack->isOper($ch)==true){
                    //是运算符
                    /**
                        3.如果发现是运算符
                        3.1 如果符号栈为空,就直接入符号栈
                        3.2. 如何符号栈,不为空,就判断
                        如果当前运算符的优先级小于等于符号栈顶的这个运算符的优先级,就计算,并把计算结果入数栈.然后把当前符号入栈
                        3.3 如何符号栈,不为空,就判断
                        如果当前运算符的优先级大于符号栈顶的这个运算符的优先级,就入栈.
                    */
                    if($operStack->isEmpty()){
                            $operStack->push($ch);
                    }else{
                            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入数栈<font size="" color=""></font>
                                $numsStack->push($res);
                            }
                            //把当前这个符号再入符号栈.//???????问题,一会在解决
                            $operStack->push($ch);            
                    }
                }else{
                    $keepNum.=$ch;                                
                    //先判断是否已经到字符串最后.如果已经到最后,就直接入栈.
                    if($index==strlen($exp)-1){
                        $numsStack->push($keepNum);
                    }else{
                        //要判断一下$ch字符的下一个字符是数字还是符号.
                        if($operStack->isOper(substr($exp,$index+1,1))){                        
                            $numsStack->push($keepNum);
                            $keepNum='';
                        }
                    }                   
                }
                $index++;//让$index指向下一个字符.
                //判断是否已经扫描完毕
                if($index==strlen($exp)){
                    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;
                    }
                 }
    
                //入栈的操作
                public function  push($val){
                    //先判断栈是否已经满了
                    if($this->top==$this->maxSize-1){
                        echo '<br/>栈满,不能添加';
                        return;
                    }
                    
                    $this->top++;
                    $this->stack[$this->top]=$val;
    
    
                }
            
                //出栈的操作,就是把栈顶的值取出
                public function pop(){
    
                    //判断是否栈空
                    if($this->top==-1){
                        echo '<br/>栈空';
                        return;
                    }
                    
                    //把栈顶的值,取出
                    $topVal=$this->stack[$this->top];
                    $this->top--;
                    return $topVal;
    
                }
    
                //显示栈的所有数据的方法.
                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];
                    }
                }
            }
    ?>
  • 相关阅读:
    install redis and used in golang on ubuntu 14.04
    在ionic项目中使用极光推送实现推送 & 服务器端代码
    安装go 1.5 & 部署
    python 简单计算器
    双指针算法
    python set()去重的底层原理
    python实现单例模式总结
    __str__和__repr的区别
    python反射详解
    python isinstance和issubclass区别
  • 原文地址:https://www.cnblogs.com/songyanan/p/10628436.html
Copyright © 2020-2023  润新知