【问题标题】:Calculator in one string with priority计算器一串优先
【发布时间】:2015-02-23 00:40:31
【问题描述】:

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

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");


        }

}

【问题讨论】:

  • 您似乎暗示这段代码基本上可以工作,但只是想要一个优化的版本?因为代码没有问题,所以这篇文章对于 SO 来说可能是题外话
  • yes :) 也没有 java 语言依赖..但是我考虑的是通用解决方案,而不是脚本或其他库等 :)
  • 除非出于特定原因,否则返回 null 通常是个坏主意。而是返回空字符串。
  • 我投票结束这个问题,因为它属于codereview.stackexchange.com
  • @BartKiers 这不是代码审查的完美选择,尽管它可能没问题。但是,代码审查是否是主题不应该影响您是否投票关闭 Stack Overflow。在 Stack Overflow 上投票结束问题的唯一原因是因为它在 Stack Overflow 上是题外话。其他 Stack Exchange 网站上的主题问题在这里并不是天生的题外话。

标签: java regex string optimization calculator


【解决方案1】:

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

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 来扩展您的操作。例如,指数或余数。这段代码取自Effective Java Item 39

一书

【讨论】:

  • 感谢我测试它:) 但最低语言专业需求。换句话说,algorytm 解决方案。具有标准功能
  • @aquavita_x 什么部分是非标准的?自 Java 5 以来,枚举一直是 Java 的一部分。这与算法无关。如果有的话,使用字符“~”进行减法是非标准的。如果您想要一个更简单的解决方案,请获取枚举并将其放在您的测试类中(使用 main 方法)。问题是解决方案无法扩展。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-30
  • 1970-01-01
  • 2016-07-31
  • 1970-01-01
  • 1970-01-01
  • 2020-06-23
相关资源
最近更新 更多