写了一个字符串表达式的计算方法(比如说"3+2*3/2-5*2d2"),按照最容易想到的办法使用多重循环嵌套
不过, 每一层嵌套的逻辑实际上是一样的, 是否可以有更简洁的表达方式呢?(比如说用一个函数
来执行每个for循环的逻辑)说明
//d是自定义的运算符,5d6表示投5次6面的骰子结果相加, 一枚硬币就可以看作一个d2的骰子
//d操作符哪里没有用循环, 其实考虑到一致性, 这里也应该可以用一个2层的循环来写
//这些代码可能有许多问题...欢迎大家指正, 比如说那个
if (下级运算符[0].equals(上级运算符[上级运算符循环]))
就从来没执行过, 因为前面的
Double.parseDoule()和Double.toString()把整数字符都转化成浮点字符了......(5=>5.0)   public String countExpression(String countmessage) throws NumberFormatException
 {
  String returncm = countmessage;
  String[] tadd = countmessage.split("\\+");
  double[] taddnum = new double[tadd.length];
  double naddtmp = 0;
   for (int iadd=0;iadd<tadd.length;iadd++)
   {
    String[] tdec = tadd[iadd].split("-");
    double[] tdecnum = new double[tdec.length];
    double ndectmp = 0;
     for (int idec=0;idec<tdec.length;idec++)
     {
      String[] tmul = tdec[idec].split("\\*");
      double[] tmulnum = new double[tmul.length];
      double nmultmp = 0;
       for (int imul=0;imul<tmul.length;imul++)
       {
        //System.out.println(tmul[imul]);
        String[] tdiv = tmul[imul].split("/");
        double[] tdivnum = new double[tdiv.length];
        double ndivtmp = 0;
         for (int idiv=0;idiv<tdiv.length;idiv++)
         {
          
          if (tdiv[idiv].equalsIgnoreCase("d"))
           tdiv[idiv] = "1d20";
          String[] tdice = tdiv[idiv].split("d");
          int intdiceaddtmp=0;
          StringBuffer tmpDiceSeq=new StringBuffer(Colors.RED);
           if (tdice[0].equals(tdiv[idiv]))
           { 
            intdiceaddtmp=Integer.parseInt(tdiv[idiv]);
            //System.out.println(intdiceaddtmp);
           }
           else
           {
            if (tdice.length > 2)
             return "骰子表达式非法";
            if (tdice[0].equals(""))
             tdice[0]="1";
          
            if (tdice.length == 1 )
            {
             
             for (int idice=0;idice<Integer.parseInt(tdice[0]);idice++)
             {
              int tmp = countDice(20);
              
              intdiceaddtmp+=tmp;
              if (idice == 0)
               tmpDiceSeq.append(tmp);
              else
               tmpDiceSeq.append("+").append(tmp);
              //intaddtmp.append("+").append(tmp);
             }
             returncm = returncm.replaceFirst(tdiv[idiv],tmpDiceSeq.append(Colors.BROWN).toString());
            }
            else
            {
             if (!checkDice(Integer.parseInt(tdice[1])))
             {
              return "这个骰子面数有点奇怪...";
             }
             for (int idice=0;idice<Integer.parseInt(tdice[0]);idice++)
             {
              int tmp = countDice(Integer.parseInt(tdice[1]));
        
              intdiceaddtmp+=tmp;
              if (idice == 0)
               tmpDiceSeq.append(tmp);
              else
               tmpDiceSeq.append("+").append(tmp);
              //intaddtmp.append("+").append(tmp);
             }
             returncm = returncm.replaceFirst(tdiv[idiv],tmpDiceSeq.append(Colors.BROWN).toString());
            }
            
            
            
           }
           tdiv[idiv] = Integer.toString(intdiceaddtmp);
            tdivnum[idiv] = Double.parseDouble(tdiv[idiv]);
            if (tdivnum[idiv]==0)
             return "不支持除法表达式中含有0";
         
         
       }
       if (tdiv[0].equals(tmul[imul]))
       {
        
        tmulnum[imul] = Double.parseDouble(tmul[imul]);//continue
       }
       else
       {
          
        ndivtmp = tdivnum[0];
        
        for (int idivnum=1;idivnum<tdivnum.length;idivnum++)
        {
         ndivtmp = ndivtmp/tdivnum[idivnum];
        }          tmulnum[imul] = ndivtmp;
       }
      
       tmul[imul] = Double.toString(tmulnum[imul]);
       
       
    }
     if (tmul[0].equals(tdec[idec]))
     {
      tdecnum[idec] = Double.parseDouble(tdec[idec]);//continue
      
     }
     else
     {
        
      nmultmp = tmulnum[0];
      
      for (int imulnum=1;imulnum<tmulnum.length;imulnum++)
      {
       nmultmp = nmultmp*tmulnum[imulnum];
      }
      tdecnum[idec] = nmultmp;
      //System.out.println(nmultmp);  
     }
     
    tdec[idec] = Double.toString(tdecnum[idec]);
    //System.out.println(tdec[idec]);
     
     
    
   }
   if (tdec[0].equals(tadd[iadd]))
   {
    taddnum[iadd] = Double.parseDouble(tadd[iadd]);//continue
   }
   else
   {
      
     ndectmp = tdecnum[0];
      
     for (int idecnum=1;idecnum<tdecnum.length;idecnum++)
     {
      ndectmp = ndectmp-tdecnum[idecnum];
     }
     taddnum[iadd] = ndectmp;       
   }
   tadd[iadd] = Double.toString(taddnum[iadd]);
     
   
   
  }
  if (tadd[0].equals(countmessage))
  {
   returncm = countmessage + Colors.DARK_GREEN + "=" +Colors.BROWN + countmessage + Colors.DARK_GREEN + "=" + Colors.RED + countmessage;
  }
  else
  {
   naddtmp = taddnum[0];
   
  for (int iaddnum=1;iaddnum<taddnum.length;iaddnum++)
  {
   //System.out.println(naddtmp+":"+iaddnum+":"+taddnum.length);
   naddtmp = naddtmp+taddnum[iaddnum];
   //System.out.println("+:"+naddtmp+":"+taddnum.length);
   }
  
    returncm = countmessage + Colors.DARK_GREEN + "=" +Colors.BROWN + returncm + Colors.DARK_GREEN + "=" + Colors.RED + Double.toString(naddtmp);
    }
  return returncm;
 }

解决方案 »

  1.   

    我也是.....写这段代码让我立刻明白了为什么书上说要先绘制流程,然后再编程....
    checkDice是检查骰子的合法性(d5的取随机数是可以的不过一般实际中没有d5)
    countDice是计算随机数(里面写的是return Math.random()*n+1)
    大体的思路是先用+分割表达式, 然后用-,以此类推, 最下层的循环计算完毕后把数值
    赋给上层替换原来不能计算的表达式
    举例而言3-2+4+3, 的一层分割为"3-2","4","3", 
    第二层分割为1(第二层可以计算减号),4(不能再计算的数值返回上层),3
    的一层再用自己的方式计算(相加)
      

  2.   

    算了,不要改了,下这个用得了.http://www.jspx.net/jar/jspx_expression.jar  String expr="(1 -3/4 )*100";
      StrExpression se = new StrExpression();
      System.out.println(se.getValue(expr));
      

  3.   

    代码
    http://www.hibernate.org.cn/viewtopic.php?t=4844&postdays=0&postorder=asc&start=0