繁体   English   中英

有人可以解释此代码的工作原理吗? (StringBuffer和StringTokenizer)

[英]Can someone explain how this code works? (StringBuffer & StringTokenizer)

我正在寻找有关如何计算数学表达式的方法,这些数学表达式可以计算诸如sin(90)10E8 ,直到我看到这些我无法完全理解其工作原理的代码。 我想以此为基础,因为我想改进我的MDAS计算器。

我很难理解这些代码。 我不熟悉StringBufferStringTokenizerMath.ceilans += mul(); ( b.toString(), "\\t" ); ,但我对三角函数和MDAS运算的工作原理有所了解。

更新:我了解什么是StringTokenizer但它与StringBuffer什么关系?

import java.util.*;

public class Expression {

    String s, x;

    double term() {
        double ans = 0;
        StringBuffer temp = new StringBuffer();
        while (s.length() > 0 && Character.isDigit(s.charAt(0))) {
            temp.append(Integer.parseInt("" + s.charAt(0)));
            s = s.substring(1);
        }
        if (s.length() > 0 && s.charAt(0) == '.') {
            temp.append('.');
            s = s.substring(1);
            while (s.length() > 0 && Character.isDigit(s.charAt(0))) {
                temp.append(Integer.parseInt("" + s.charAt(0)));
                s = s.substring(1);
            }
        }
        if (s.length() > 0 && (s.charAt(0) == 'e' || s.charAt(0) == 'E')) {
            temp.append('e');
            s = s.substring(1);
            temp.append(s.charAt(0));
            s = s.substring(1);
            while (s.length() > 0 && Character.isDigit(s.charAt(0))) {
                temp.append(Integer.parseInt("" + s.charAt(0)));
                s = s.substring(1);
            }
        }
        ans = Double.valueOf(temp.toString()).doubleValue();
        return ans;
    }

    double paren() {
        double ans;
        if (s.charAt(0) == '(') {
            s = s.substring(1);
            ans = add();
            s = s.substring(1);
        } else {
            ans = term();
        }
        return ans;
    }

    double exp() {
        boolean neg = false;
        if (s.charAt(0) == '-') {
            neg = true;
            s = s.substring(1);
        }
        double ans = paren();
        while (s.length() > 0) {
            if (s.charAt(0) == '^') {
                s = s.substring(1);
                boolean expNeg = false;
                if (s.charAt(0) == '-') {
                    expNeg = true;
                    s = s.substring(1);
                }
                double e = paren();
                if (ans < 0) {
                    double x = 1;
                    if (Math.ceil(e) == e) {
                        if (expNeg)
                            e *= -1;
                        if (e == 0)
                            ans = 1;
                        else if (e > 0)
                            for (int i = 0; i < e; i++)
                                x *= ans;
                        else
                            for (int i = 0; i < -e; i++)
                                x /= ans;
                        ans = x;
                    } else {
                        ans = Math.log(-1);
                    }
                } else if (expNeg)
                    ans = Math.exp(-e * Math.log(ans));
                else
                    ans = Math.exp(e * Math.log(ans));
            } else
                break;
        }
        if (neg)
            ans *= -1;
        return ans;
    }

    double trig() {
        double ans = 0;
        boolean found = false;
        if (s.indexOf("sin") == 0) {
            s = s.substring(3);
            ans = Math.sin((trig() * Math.PI) / 180);
            found = true;
        } else if (s.indexOf("cos") == 0) {
            s = s.substring(3);
            ans = Math.cos((trig() * Math.PI) / 180);
            found = true;
        } else if (s.indexOf("tan") == 0) {
            s = s.substring(3);
            ans = Math.tan((trig() * Math.PI) / 180);
            found = true;
        }
        if (!found) {
            ans = exp();
        }
        return ans;
    }

    double mul() {
        double ans = trig();
        if (s.length() > 0) {
            while (s.length() > 0) {
                if (s.charAt(0) == '*') {
                    s = s.substring(1);
                    ans *= trig();
                } else if (s.charAt(0) == '/') {
                    s = s.substring(1);
                    ans /= trig();
                } else
                    break;
            }
        }
        return ans;
    }

    double add() {
        double ans = mul();
        while (s.length() > 0) {
            if (s.charAt(0) == '+') {
                s = s.substring(1);
                ans += mul();
            } else if (s.charAt(0) == '-') {
                s = s.substring(1);
                ans -= mul();
            } else {
                break;
            }
        }
        return ans;
    }

    public double evaluate() {
        s = x.intern();
        double last = add();
        return last;
    }

    public Expression(String s) {
        StringBuffer b = new StringBuffer();
        StringTokenizer t = new StringTokenizer(s, " ");
        while (t.hasMoreElements())
            b.append(t.nextToken());
        t = new StringTokenizer(b.toString(), "\t");
        b = new StringBuffer();
        while (t.hasMoreElements())
            b.append(t.nextToken());
        x = b.toString();
    }

    public String toString() {
        return x.intern();
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.print("Enter expression: ");
        Expression e = new Expression(sc.nextLine());
        System.out.println("\n" + e + " = " + e.evaluate() + "\n");
    }
}

该程序通常读取数学表达式的字符串表示形式,并解释和执行该表达式。 至于Java元素,您很好奇:

StringBuffer是处理String对象的更有效的接口。

StringTokenizer(String, String)是用于将字符串分解为令牌的类。 在此构造函数中,第一个参数是可拆分为令牌的字符串,第二个参数是用于创建这些令牌的定界符。

Math.ceil()返回大于或等于自变量且等于数学整数的最小(最接近负无穷大)双精度值。

StringBuffer.toString()写出一个代表缓冲区中数据的String

\\t是标签

+=-=是{add / subject}赋值运算符,它们将{add / subject}右操作数赋给左操作数,并将结果赋给左操作数。 例如

int x = 0;
x += 2; // x is now 2

请参阅http://docs.oracle.com/javase/7/docs/api/java/lang/StringBuffer.html上有关StringBuffer的javadoc

有关StringTokenizer的信息,请参见javadoc, 网址http://docs.oracle.com/javase/7/docs/api/java/util/StringTokenizer.html

我将尝试评论所有明显的行号

import java.util.*;

public class Expression {

    String s, x;

    double term() {
        double ans = 0;
        StringBuffer temp = new StringBuffer(); //Efficient than simple String
        while (s.length() > 0 && Character.isDigit(s.charAt(0))) { //Check if the first character is a digit
            temp.append(Integer.parseInt("" + s.charAt(0))); //If true, add to temp String
            s = s.substring(1);
        }
        if (s.length() > 0 && s.charAt(0) == '.') {
            temp.append('.');
            s = s.substring(1);
            while (s.length() > 0 && Character.isDigit(s.charAt(0))) {
                temp.append(Integer.parseInt("" + s.charAt(0)));
                s = s.substring(1);
            }
        }
        if (s.length() > 0 && (s.charAt(0) == 'e' || s.charAt(0) == 'E')) {
            temp.append('e');
            s = s.substring(1);
            temp.append(s.charAt(0));
            s = s.substring(1);
            while (s.length() > 0 && Character.isDigit(s.charAt(0))) {
                temp.append(Integer.parseInt("" + s.charAt(0)));
                s = s.substring(1);
            }
        }
        ans = Double.valueOf(temp.toString()).doubleValue();
        return ans;
    }

    double paren() {
        double ans;
        if (s.charAt(0) == '(') {
            s = s.substring(1);
            ans = add();
            s = s.substring(1);
        } else {
            ans = term();
        }
        return ans;
    }

    double exp() {
        boolean neg = false;
        if (s.charAt(0) == '-') {
            neg = true;
            s = s.substring(1);
        }
        double ans = paren();
        while (s.length() > 0) {
            if (s.charAt(0) == '^') {
                s = s.substring(1);
                boolean expNeg = false;
                if (s.charAt(0) == '-') {
                    expNeg = true;
                    s = s.substring(1);
                }
                double e = paren();
                if (ans < 0) {
                    double x = 1;
                    if (Math.ceil(e) == e) { //Check Math.ceil documentation at http://docs.oracle.com/javase/7/docs/api/java/lang/Math.html#ceil(double)
                        if (expNeg)
                            e *= -1;
                        if (e == 0)
                            ans = 1;
                        else if (e > 0)
                            for (int i = 0; i < e; i++)
                                x *= ans;
                        else
                            for (int i = 0; i < -e; i++)
                                x /= ans;
                        ans = x;
                    } else {
                        ans = Math.log(-1); //http://docs.oracle.com/javase/7/docs/api/java/lang/Math.html#log(double)
                    }
                } else if (expNeg)
                    ans = Math.exp(-e * Math.log(ans));
                else
                    ans = Math.exp(e * Math.log(ans)); //http://docs.oracle.com/javase/7/docs/api/java/lang/Math.html#exp(double)
            } else
                break;
        }
        if (neg)
            ans *= -1;
        return ans;
    }

    double trig() {
        double ans = 0;
        boolean found = false;
        if (s.indexOf("sin") == 0) {
            s = s.substring(3);
            ans = Math.sin((trig() * Math.PI) / 180);
            found = true;
        } else if (s.indexOf("cos") == 0) {
            s = s.substring(3);
            ans = Math.cos((trig() * Math.PI) / 180);
            found = true;
        } else if (s.indexOf("tan") == 0) {
            s = s.substring(3);
            ans = Math.tan((trig() * Math.PI) / 180);
            found = true;
        }
        if (!found) {
            ans = exp();
        }
        return ans;
    }

    double mul() {
        double ans = trig();
        if (s.length() > 0) {
            while (s.length() > 0) {
                if (s.charAt(0) == '*') {
                    s = s.substring(1);
                    ans *= trig();
                } else if (s.charAt(0) == '/') {
                    s = s.substring(1);
                    ans /= trig();
                } else
                    break;
            }
        }
        return ans;
    }

    double add() {
        double ans = mul();
        while (s.length() > 0) {
            if (s.charAt(0) == '+') {
                s = s.substring(1);
                ans += mul();
            } else if (s.charAt(0) == '-') {
                s = s.substring(1);
                ans -= mul();
            } else {
                break;
            }
        }
        return ans;
    }

    public double evaluate() {
        s = x.intern();
        double last = add();
        return last;
    }

    public Expression(String s) {
        StringBuffer b = new StringBuffer();
        StringTokenizer t = new StringTokenizer(s, " "); //Creates a iterable t object so you can iterate over each "word" separate by space
        while (t.hasMoreElements())
            b.append(t.nextToken());
        t = new StringTokenizer(b.toString(), "\t");
        b = new StringBuffer();
        while (t.hasMoreElements())
            b.append(t.nextToken());
        x = b.toString();
    }

    public String toString() {
        return x.intern();
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.print("Enter expression: ");
        Expression e = new Expression(sc.nextLine());
        System.out.println("\n" + e + " = " + e.evaluate() + "\n");
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM