利用正则表达式计算表达式的值

方法一:
在网上看资料的时候,无意看到一道关于Java的题:

原意应该是随意输入一个合法的表达式,怎样用Java编写一个程序计算此表达式的值,

开始的时候觉得很简单,不就是+,-,*,/和括号吗?觉得应该很轻松就可以把此程序搞定,可是后来仔细一分析,总觉得如果自己解析,利用String提供的方法,似乎很难把"("解析出来,但是如果此表达式有很多很多括号呢?怎样用程序判断那些括号是一对?百思不得其解...我也知道如果用正则式也许会有解决的方法,但一直都只用过简单的正则式,没有深入理解过,就反而更难了.

后面才在网上找了一个高手写的正则式java程序,我感觉非常不错,精简,且运行效果理想,看来真应该好好学学正则式..

 

package com.color.io;

import java.util.regex.*;
import java.util.*;
/**
*利用正则式计算表达式的值
*@author: Eastsun
*@version: 0.5 07.2.26
*/
public class Calculate{
    public static final String NUM_PATTERN =                     //数字的匹配模式
                                "(?:(?<=[//+//-//*//(/]|^)[+-]|)"   //前缀判断,判断前面的+-是否为符号
                                    +"(?:"                       //数字及小数点部分,  0. 以及 .0 都是合法的数字
                                        +"(?://d*//.)?//d+|"     //.0 的情形
                                        +"/d+(?:/./d*)?"      //0. 的情形
                                    +")"
                               +"(?!//d|//.)";                   //边界条件
    public static final String BRA_PATTERN =
                                "/((NUM)/)".replace("NUM",NUM_PATTERN);
    public static final String ADD_PATTERN =
                                "(NUM)//+(NUM)".replace("NUM",NUM_PATTERN);   
    public static final String SUB_PATTERN =
                                "(NUM)-(NUM)".replace("NUM",NUM_PATTERN);
    public static final String MUL_PATTERN =
                                "(NUM)//*(NUM)".replace("NUM",NUM_PATTERN);
    public static final String DIV_PATTERN =
                                "(NUM)/(NUM)".replace("NUM",NUM_PATTERN);
    public static final Pattern BRA =Pattern.compile(BRA_PATTERN);
    public static final Pattern ADD_OR_SUB =Pattern.compile("(?<=[^//+//-//*/]|^)(?:"+ADD_PATTERN+"|"+SUB_PATTERN+")(?=[^//*/]|$)");
    public static final Pattern MUL_OR_DIV =Pattern.compile("(?<![//*/])(?:"+MUL_PATTERN+"|"+DIV_PATTERN+")");
   
    private static double operator(Matcher m,int index){
        index =index*2;
        double a,b;
        if(m.group(1)!=null){
            a =Double.parseDouble(m.group(1));
            b =Double.parseDouble(m.group(2));
        }
        else{
            index ++;
            a =Double.parseDouble(m.group(3));
            b =Double.parseDouble(m.group(4));
        }
        double r =0.0;
        switch(index){
            case 0:
                r =a+b;
                break;
            case 1:
                r =a-b;
                break;
            case 2:
                r =a*b;
                break;
            case 3:
                r =a/b;
                break;
        }
        return r;
    }
    public static double eval(String str){
        StringBuilder sb =new StringBuilder(str.replaceAll("/s+",""));
        while(true){
            Matcher m =BRA.matcher(sb);
            if(m.find()){
                sb.replace(m.start(),m.end(),m.group(1));
            }
            else{
                int index =1;
                m =MUL_OR_DIV.matcher(sb);
                if(!m.find()){
                    index --;
                    m =ADD_OR_SUB.matcher(sb);
                    if(!m.find()) break;
                }
                sb.replace(m.start(),m.end(),""+operator(m,index));
            }
        }
        return Double.parseDouble(sb.toString());
    }                           
    public static void main(String[] args){
        Scanner scan =new Scanner(System.in);
        while(true){
            System.out.print("/nEnter a expression :");
            String str =scan.next();
            if(str.equals("exit")) break;
            System.out.print(str +" = "+eval(str));
        }
    }
}

 

 

 

方法二:

这个的正则表达式没有括号在里边。

package test;

import java.util.Stack;

public class Arithmetic1 {
 static String[] operater = new String[20];
 static String[] number = new String[20];

 public int countExpression(String str) {

  Stack countStack1 = new Stack();
  Stack countStack2 = new Stack();
  int result = 0;
  number = str.split("///|//*|//+|//-");
  operater = str.split("//d+");
  for (int i = 0; i < number.length; i++) {
   countStack1.push(number[i]);
   if (i != number.length - 1) {
    countStack1.push(operater[i + 1]);

   }
  }
  while (!countStack1.isEmpty())
   countStack2.push(countStack1.pop());
  String op;
  while (!countStack2.isEmpty()) {
   result = 0;
   op = countStack2.pop().toString();
   if (op.equals("*")) {
    result = Integer.parseInt(countStack1.pop().toString())
      * Integer.parseInt(countStack2.pop().toString());
    countStack1.push(result);

    continue;
   }
   if (op.equals("/")) {
    result = Integer.parseInt(countStack1.pop().toString())
      / Integer.parseInt(countStack2.pop().toString());
    countStack1.push(result);
    continue;
   }
   countStack1.push(op);

  }
  while (!countStack1.isEmpty())
   countStack2.push(countStack1.pop());

  while (!countStack2.isEmpty()) {
   result = 0;
   op = countStack2.pop().toString();
   if (op.equals("+")) {
    result = Integer.parseInt(countStack1.pop().toString())
      + Integer.parseInt(countStack2.pop().toString());
    countStack1.push(result);
    continue;
   }
   if (op.equals("-")) {
    result = Integer.parseInt(countStack1.pop().toString())
      - Integer.parseInt(countStack2.pop().toString());
    countStack1.push(result);
    continue;
   }
   countStack1.push(op);

  }
  return result;
  // System.out.println(result);

 }

 public static void main(String[] args) {
  int num;
  Arithmetic1 ct = new Arithmetic1();
  num = ct.countExpression("222+2*6*7-112*2+5*2-6*7");
  System.out.println(num);
  
 }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值