爪哇国新游记之二十二----算术表达式计算求值

代码:

import java.util.ArrayList;
import java.util.List;

// 辅助类
class Item{
    String value;
    boolean isNumber;

    public Item(String value,boolean isNumber){
        this.value=value;
        this.isNumber=isNumber;
    }

    public Item(char c,boolean isNumber){
        this.value=String.valueOf(c);
        this.isNumber=isNumber;
    }

    public String toString(){
        return ""+value+" & "+isNumber;
    }
}

/**
 * 算术表达式求值
 */
public class ArithCaculator{
    private String line;// 输入的算式
    private String result;// 计算得到的结果

    public ArithCaculator(String line){
        this.line=line;
        int length=line.length();

        // 得到包含数字和操作符的列表
        List<Item> ls=new ArrayList<Item>();
        String str="";
        for(int i=0;i<length;i++){
            char ch=line.charAt(i);

            if((ch>=‘0‘ && ch<=‘9‘) || ch==‘.‘){
                str+=ch;
            }else if(ch==‘+‘ || ch==‘-‘ || ch==‘*‘ || ch==‘/‘ || ch==‘(‘ || ch==‘)‘ ){
                if(str.length()>0){
                    ls.add(new Item(str,true));
                    str="";
                }

                ls.add(new Item(ch,false));
            }

            if(i==length-1 && str.length()>0){
                ls.add(new Item(str,true));
            }
        }

        // 得到后序表达式
        ls=getPostfix(ls);

        // 计算后序表达式
        this.result=getValue(ls);
    }

    // 对后序表达式进行计算
    private String getValue(List<Item> ls){
        Stack<Item> stack=new Stack<Item>(Item.class,ls.size());
        double result;

        for(Item it:ls){
            if(it.isNumber){
                stack.push(it);
            }else{
                // 栈先进后出所以颠倒
                double op2=Double.parseDouble(stack.pop().value);
                double op1=Double.parseDouble(stack.pop().value);

                result=0;
                char ch=it.value.charAt(0);

                if(ch==‘+‘){
                    result=op1+op2;
                }else if(ch==‘-‘){
                    result=op1-op2;
                }else if(ch==‘*‘){
                    result=op1*op2;
                }else if(ch==‘/‘){
                    result=op1/op2;
                }

                stack.push(new Item(String.valueOf(result),true));
            }
        }

        return stack.pop().value;
    }

    // 得到后序表达式
    private List<Item> getPostfix(List<Item> ls){
        List<Item> retval=new ArrayList<Item>();
        Stack<Character> stack=new Stack<Character>(Character.class,ls.size());

        for(Item it:ls){
            if(it.isNumber){
                retval.add(it);
            }else{
                if("+".equals(it.value) || "-".equals(it.value) ){
                    gotOper(stack,retval,it.value,1);
                }else if("*".equals(it.value) || "/".equals(it.value) ){
                    gotOper(stack,retval,it.value,2);
                }else if("(".equals(it.value)){
                    stack.push(‘(‘);
                }else if(")".equals(it.value)){
                    gotParen(stack,retval,‘)‘);
                }
            }
        }

        while(stack.isEmpty()==false){
            retval.add(new Item(stack.pop(),false));
        }

        return retval;
    }

    private void gotOper(Stack<Character> stack,List<Item> ls,String opThis,int prec){
        while(stack.isEmpty()==false){
            char opTop=stack.pop();

            if(opTop==‘(‘){
                stack.push(opTop);
                break;
            }else{
                int prec2=2;

                if(opTop==‘+‘ || opTop==‘-‘){
                    prec2=1;
                }

                if(prec2<prec){
                    stack.push(opTop);
                    break;
                }else{
                    ls.add(new Item(opTop,false));
                }
            }
        }

        stack.push(opThis.charAt(0));
    }

    private void gotParen(Stack<Character> stack,List<Item> ls,char ch){
        while(stack.isEmpty()==false){
            char chTop=stack.pop();

            if(chTop==‘(‘){
                break;
            }else{
                ls.add(new Item(chTop,false));
            }
        }
    }

    public String getLine() {
        return line;
    }

    public String getResult() {
        return result;
    }

    public static void main(String[] args){
        String[] arr=new String[]{"2+3+5","2+(3*5)-6","4+5*(1+2)","1*2+3*4","(3+4)*5/2+33","5+17+12.5","8.0/(3.0-(8.0/3.0))","((10.0*10.0)-4.0)/4.0"};

        for(String str:arr){
            ArithCaculator a=new ArithCaculator(str);
            System.out.println(a.getLine()+"="+a.getResult());
        }
    }
}

输出:

2+3+5=10.0
2+(3*5)-6=11.0
4+5*(1+2)=19.0
1*2+3*4=14.0
(3+4)*5/2+33=50.5
5+17+12.5=34.5
8.0/(3.0-(8.0/3.0))=23.99999999999999
((10.0*10.0)-4.0)/4.0=24.0

爪哇国新游记之二十二----算术表达式计算求值,布布扣,bubuko.com

时间: 2024-10-26 15:03:23

爪哇国新游记之二十二----算术表达式计算求值的相关文章

爪哇国新游记之十二----线程创建的两种形式

public class Thread1 extends Thread{ public void run(){ int i=0; while(i<10){ i++; System.out.println(i); } } public static void main(String[] args){ Thread1 t=new Thread1(); t.start(); } } public class Thread2 implements Runnable{ @Override public v

爪哇国新游记之二十八----从url指定的地址下载一个文件到本地

package download; import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; import java.io.OutputStream; import java.net.URL; import java.net.URLConnection; import java.util.zip.GZIPInputStream; /** * 从url指定的地址下载一个文件到本地 * 2014

爪哇国新游记之二十五----图及其遍历查找

代码: import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; // 顶点类 class Vertex{ String name;// 名称 boolean visited;// 是否已访问

爪哇国新游记之二十四----二叉树

/** * 二叉树节点类 * */ class Node<T extends Comparable> { public Node(T data){ this.data=data; } T data; Node<T> left; Node<T> right; } /** * 二叉树类 */ public class BinaryTree<T extends Comparable> { /** * 根節點 */ private Node<T> roo

爪哇国新游记之二十一----快算24

四张牌,通过四则运算得到24,一个数限用一次,快者为胜. 代码: import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; /** * 快算24 * @author heyang * */ public class Caculator{ private double anticipate;// 预期结果 private double op1;// 操作数一

爪哇国新游记之二十七----数组的二分查找

代码: import java.util.ArrayList; import java.util.List; public class Bit { int max; int min; int[] arr; public Bit(int[] arrInput) { // 找出极值 for (int i = 0; i < arrInput.length; i++) { if (max < arrInput[i]) { max = arrInput[i]; } if (min > arrInp

爪哇国新游记之十八----泛型栈类

import java.lang.reflect.Array; /** * 泛型栈 * * @param <T> */ public class Stack<T>{ private Class<T> type;// 栈元素所属的类 private int size;// 栈深度 private T[] arr;// 用数组存储 private int top;// 栈顶元素的下标 public Stack(Class<T> type,int size){ t

爪哇国新游记之十九----使用Stack检查数字表达式中括号的匹配性

/** * 辅助类 * 用于记载字符和位置 * */ class CharPos{ char c; int pos; public CharPos(char c,int pos){ this.c=c; this.pos=pos; } } /** * 括号检查类 * */ public class BracketChecker{ /** * 检查函数 * @param str * @return * @throws Exception */ public static boolean check(

爪哇国新游记之十六----泛型单链表类

/** * 单链表节点类 * @param <T> */ class Node<T extends Object>{ protected T value; protected Node next; } /** * 单链表类 * @param <T> */ public class ChainList<T extends Object>{ private Node<T> first; public void addTail(T t){ Node&l