PHP 计算字符串表达式(二)

  • A+
所属分类:PHP 数据结构

       由于eval()在安全性上存在问题,因此需考虑使用其余办法解决字符串表达式的计算。在数据结构中,栈(stack)是一种只能在一端进行插入和删除操作的特殊线性表。它按照先进后出的原则存储数据,先进入的数据存入栈底,最后的数据存在栈顶。

        PHP 计算字符串表达式(二)

       中缀表达式是一种通用的逻辑或算术公式表达方法,操作符以中缀形式处于操作数之间。而后缀表达式则是将运算符放在两个操作数之后,严格按照从左向右的顺序进行执行。

      我们可以利用一个字符栈将中缀表达式转化为后缀表达式,再利用数字栈计算,得到运算结果。

      首先,需要规定运算符的优先级来判断进行出栈、入栈操作。通常,+、-运算符的优先级要低于/、*、%。

      然后,我们定义两个数组optstack(操作符栈)、numstack(数字栈)分别用于存储不同的数据。

     接下来,需要将字符串表达式转化为数组,可以规定每个字符按相同的分隔符隔离,以保证数据不会混淆。也可以利用利用递归判断,从而判断个位数、十位数....再利用循环判断每个数组元素的类型。

     入栈、出栈需遵从以下规则:

     ①如果元素为数字,则直接将数字存入后缀表达式中

  <?php
       if(is_numeric($s))
       {
           $this->newstr .= $s.'|';
       }
  ?>

     ②如果元素为左括号(“(”),则无条件入栈

     ③如果元素为右括号(“)”),则出栈,直至栈顶为左括号,并将左括号删除。

  <?php
      if($s == ')')
      {
           while(($opt = array_pop($this->optstack))!='')
        {
            if($opt == '(')break;
          $this->newstr .= $opt.'|';
        }
      }
  
  ?>

     ④如果为运算符,则需要判断运算符优先级,如果当前元素优先级高于栈顶,则入栈;若低于,则执行出栈操作。

  <?php
      if(in_array($s,array('+','-','/','*','%'))&& count($this->optstack)>0)
      {                    
          $strpop = $this->optstack[count($this->optstack)-1];
          if($this->level($s, $strpop)!=1)
          {
              for($j= count($this->optstack)-1;$j>=0;$j--)
              {
                  if($this->optstack[$j]=='(')
               {
                                break;
               }
                 $this->newstr   .= $this->optstack[$j].'|';
                 unset($this->optstack[$j]);
              }
           }else{
                $this->optstack[] = $s;
            }
      }
  
  ?>

       最后,利用数字栈运算后缀表达式。运算需遵从以下规则:

      ①如果元素为数字,则将数字直接入栈。

     ②如果元素为运算符,则将栈内的两个数字出栈,进行运算,再将结果入栈。

     ③栈顶(栈顶)即为运算结果。

 <?php
    for($k = 0;$k<count($houzhi);$k++)
    {
      if(in_array($houzhi[$k], array('+','-','*','/','%')))
      {                        
$res = $this->yunsuan(array_pop($this->numstack),array_pop($this->numstack), $houzhi[$k]);
         $this->numstack[]   = round($res,2);  
      }else{
         $this->numstack[] = $houzhi[$k];
       }
    }
     if(count($this->numstack))$this->result = $this->numstack[0];
 
 ?>

     下载源代码


avatar

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: