一个字符串中的计算器具有优先级

Calculator in one string with priority

如何在没有堆栈的情况下创建更好的解决方案或以其他方式优化此代码。

import java.util.*;

public class Calc
{

    // (15+25)+((15+25)+5)


    public static String calc(String a, String b, String operator){


            switch (operator) {

                    case "+": return Double.valueOf(a) + Double.valueOf(b)+"";

                    case "~": return Double.valueOf(a) - Double.valueOf(b)+"";

                    case "*": return Double.valueOf(a) * Double.valueOf(b)+"";

                    case "/": return Double.valueOf(a) / Double.valueOf(b)+"";

                }

            return null;

        }


    //difference with operator '-'..i replace this operator to ~

    public static String minustotild(String s){

            String result = ""+s.charAt(0);

            for (int i = 1; i < s.length(); i++){

                    if ((s.charAt(i) == '-') && ("+-*(/~".indexOf(s.charAt(i-1)) == -1))   // if previous char is not a symbol( is digit)

                        result += ""+'~';

                    else result +=""+s.charAt(i);

                }

            return result;

        }

    public static String operate(String expression){


            String num[];   int index = -1;  
            Character priorityOperator='/';  // default
            String operators;
            while (!((  operators = expression.replaceAll("[^*+/~]","")  ).isEmpty()))     // while have operator..
                {   

                    if ( (index = operators.indexOf('/')) == -1){        // choose priority operator
                        priorityOperator = '*';
                        if  ( (index = operators.indexOf('*')) == -1){
                                priorityOperator=operators.charAt(0);
                                index = operators.indexOf(priorityOperator);
                            }
                    }
                    num = expression.split("[^0-9\-.]"); // сплитим все числа..

                    // заменяем строкое представление арифметики,на строковой результат с помощью калк(). 
                    expression=expression.replaceFirst(num[index]+"\"+priorityOperator+num[index+1], calc(num[index],num[index+1],""+priorityOperator)); 

                }

            return expression;

        }


    public static String operateBracket(StringBuilder s, int startIndex){
            // ''
            // 3+4+(4+(3+3)+5)+(4+)
            if (startIndex == -1) {        // если скобок нету то оперируем .
                    return (operate(s.toString()));
                }
            else {   
                    int k = 1;
                    for (int i=startIndex+1; i < s.length(); i++){

                        if (s.charAt(i) == '(')  
                                k++;
                            else if ((s.charAt(i) == ')')) 
                                {
                                    if (k == 1) {    // нашли конец первой скобки. не знаю как лучше сделать)

                                            String newBracket = s.substring(startIndex+1, i);

                                            s=s.replace(startIndex,i+1,operateBracket(new StringBuilder(newBracket), newBracket.indexOf(""+'(')));

                                        }
                                    k--;
                                }

                        }
                }

            return operate(s.toString());

        }





    public static void main(String[] args){

        Scanner s = new Scanner( System.in );
        String b = s.next();

             do  {

                   StringBuilder a = new StringBuilder(minustotild(b));
                   System.out.println(" result = "+operateBracket(a,a.indexOf(""+'(')));

              }   while ( (b = s.next()) != "null");


        }

}

首先,您可以创建一个操作界面:

public interface Operation
{
    double apply(double x, double y);
}

然后,您创建具体操作:

public enum BasicOperation implements Operation
{
    PLUS("+") {
        public double apply(double x, double y) { return x + y; }
    },
    MINUS("-") {
        public double apply(double x, double y) { return x - y; }
    },
    TIMES("*") {
        public double apply(double x, double y) { return x * y; }
    },
    DIVIDE("/") {
        public double apply(double x, double y) { return x / y; }
    };

    private final String symbol;
    BasicOperation(String symbol)
    {
        this.symbol = symbol;
    }

    @Override
    public String toString()
    {
        return symbol;
    }
}

然后创建使用这些操作的逻辑:

public class ExtensibleEnumOperationTest
{
    public static void main(String[] args)
    {
        Scanner input = new Scanner(System.in);
        System.out.print("Enter a number (i.e. 1.43): ");
        double x = input.nextDouble();
        System.out.print("Enter another number: ");
        double y = input.nextDouble();
        input.close();
        System.out.println();
        System.out.println("Testing Basic Operations using Bounded Type Token (Item 29)");
        test(BasicOperation.class, x, y);

        System.out.println("Testing Basic Operations using Bounded Wildcard Type (Item 28)");
        test(Arrays.asList(BasicOperation.values()), x, y);

        System.out.println("Testing a single operation:");
        Operation op = BasicOperation.PLUS;
        System.out.println(x + " + " + y + " = " + op.apply(x, y));     
    }

    private static <T extends Enum<T> & Operation> void test(Class<T> opSet,
        double x, double y)
    {
        for (Operation op : opSet.getEnumConstants())
            System.out.printf("%f %s %f = %f%n", x, op, y, op.apply(x, y));
        System.out.println();
    }

    private static void test(Collection<? extends Operation> opSet, double x,
            double y)
    {
        for (Operation op : opSet)
            System.out.printf("%f %s %f = %f%n", x, op, y, op.apply(x, y));
        System.out.println();
    }
}

这应该可以正常工作。此外,它还允许您通过创建另一个实现 Operationenum 来扩展您的操作。例如,指数或余数。这段代码摘自书有效Java第39条