java - 如何使用正则表达式分割字符串并插入到ArrayList中?

标签 java calculator

我试图通过将中缀转换为后缀来构建一个计算器,但我在处理 cos、sin 和 tan 时遇到了麻烦。我当前的方法是使用正则表达式将输入字符串按 cos、sin 等和数字拆分,然后将它们放入 ArrayList 的索引中。我已经能够将 cos0 分成两个 ArrayList 索引,但应该保存 cos 的索引却变成了空。我不知道是我使用了错误的正则表达式还是其他原因。

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;
import java.util.Stack;
import java.util.regex.Matcher;



public class Calculator {

    //String sin = "sin";
    //String cos = "cos";
    //String tan = "tan";

    public static void main(String[] args) {
        new Calculator().run();
    }

    public void run() {
        Calculator Eval = new Calculator();
        Scanner keyboard = new Scanner(System.in);
        System.out.println("Please give an equation.");

        String input = keyboard.next();

        System.out.print(Eval.infixToPostfix(input));
    }

    public double infixToPostfix(String input)
    {

        Stack<String>infixStack = new Stack<>();
        ArrayList<String> exp = new ArrayList<>(Arrays.asList(input.split("(cos|tan|sin\\d\\D)")));

        String infix = "";

        for (int i = 0; i < exp.size(); i++)
        {
            if(exp.get(i).equals("")){
                continue;
            }
            if (exp.get(i).matches("([\\d])")) {

                infix = infix + exp.get(i);

            }else if(exp.get(i).matches("([\\D])"))
            {
                while(!infixStack.empty() && !infixStack.peek().matches("[\\(\\[\\{\\^]") && OperatorPriority(infixStack.peek(), exp.get(i) ))
                {
                    infix = infix + infixStack.peek();
                    infixStack.pop();
                }
                infixStack.push(exp.get(i));
            }else if(exp.get(i).matches("[(]"))
            {
                infixStack.push(exp.get(i));
            }else if(exp.get(i).matches("[)]"))
            {
                while(!infixStack.empty() && !infixStack.peek().matches("[(]"));
            {
                infix = infix + infixStack.peek();
                infixStack.pop();
            }
            infixStack.pop();
            }else if(exp.get(i).matches("[\\^]"))
            {
                infixStack.push(exp.get(i));
            }else if(exp.get(i).matches("[\\[]"))
            {
                infixStack.push(exp.get(i));
            }else if(exp.get(i).matches("[\\]]"))
            {
                while(!infixStack.empty() && !infixStack.peek().matches("[\\(\\[]"))
                {
                    infix = infix + infixStack.peek();
                    infixStack.pop();
                }

                infixStack.pop();
            } else if(exp.get(i).matches("[\\{]"))
            {
                infixStack.push(exp.get(i));
            }else if(exp.get(i).matches("[\\}]"))
            {
                while(!infixStack.empty() && !infixStack.peek().matches("[\\(\\{\\[]"))
                {
                    infix = infix + infixStack.peek();
                    infixStack.pop();
                }
                infixStack.pop();
            }
        }

        while(!infixStack.empty())
        {
            infix = infix + infixStack.peek();
            infixStack.pop();
        }
        return evaluatePostFix(infix);
    }

    public double evaluatePostFix(String infix) {
        Stack<Double> equation = new Stack<Double>();
        ArrayList<String> postfixArray = new ArrayList<>(Arrays.asList(infix.split("(?<=[\\w'(cos|tan|sin)'\\d])|(?=[\\w'(cos|tan|sin)'\\d])")));


        double first;
        double second;

        try {
            for (int i = 0; i < postfixArray.size(); i++) {
                if (postfixArray.get(i).matches("([\\d])")) {
                    double d = Double.parseDouble(postfixArray.get(i));
                    equation.push(d - '0');
                }else if(postfixArray.get(i).matches("([sin])"))
                {
                    first = equation.pop();
                    //second = equation.pop();
                    double result = Math.sin(Math.toRadians(first));
                    equation.push(result);
                }else if(postfixArray.get(i).matches("([cos])"))
                {
                    first = equation.pop();
                    //second = equation.pop();
                    double result = Math.cos(Math.toRadians(first));
                    equation.push(result);
                }else if(postfixArray.get(i).matches("([tan])"))
                {
                    first = equation.pop();
                    //second = equation.pop();
                    double result = Math.tan(Math.toRadians(first));
                    equation.push(result);
                }

                if (postfixArray.get(i).matches("[*]")) {
                    first = equation.pop();
                    second = equation.pop();
                    double result = first * second;
                    equation.push(result);
                }

                if (postfixArray.get(i).matches("[/]")) {
                    first = equation.pop();
                    second = equation.pop();
                    double result = second / first;
                    equation.push(result);
                }

                if (postfixArray.get(i).matches("[+]")) {
                    first = equation.pop();
                    second = equation.pop();
                    double result = first + second;
                    equation.push(result);
                }

                if (postfixArray.get(i).matches("[-]")) {
                    first = equation.pop();
                    second = equation.pop();
                    double result = first - second;
                    equation.push(result);
                }

                if (postfixArray.get(i).matches("[(^)]")) {
                    first = equation.pop();
                    second = equation.pop();
                    double result = Math.pow(first, second);
                    equation.push(result);
                }
            }

            if (!equation.isEmpty()) {
                return equation.pop();
            } else
                return 0.0;
        } catch (Exception e ) {
            return 0.0;
        }
    }

    int OperatorWeight(String op)
    {
        int weight = 1;
        if(op.equals("+") || op.equals("-"))
        {
            weight = 1;
        }else if(op.equals("*") || op.equals("/") )
        {
            weight = 2;
        }else if(op.equals("^"))
        {
            weight = 3;
        }
        return weight;
    }

    boolean OperatorPriority(String operator1, String operator2)
    {
        int weight1 = OperatorWeight(operator1);
        int weight2 = OperatorWeight(operator2);

        if(weight1 == weight2)
        {
            return true;
        }
        return weight1 > weight2;
    }
}

最佳答案

假设输入格式如下:

valid - cos49

invalid - cos43.54

invalid - sin(angle)

您可以将字符串分为两组:

  1. sin|cos|tan
  2. 数字

所以你的正则表达式应该是这样的:

Pattern p = Pattern.compile("(sin|cos|tan)|(\\d+)");
Matcher m = p.matcher("cos60");
ArrayList<String> a = new ArrayList<>();
while (m.find())
    a.add(m.group(0));

System.out.println(a.toString());

Read匹配器类如何工作。希望对您有帮助

关于java - 如何使用正则表达式分割字符串并插入到ArrayList中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40526696/

相关文章:

python - 输入变量后的 If 语句打印

c++ - 有没有一种方法可以在 C++ 中以这种格式将输入限制为整数/ double

java - Hibernate - 在事务完成时强制清理容器资源

java - launchpad 提示缺少 maven-site-plugin 但我根本不使用它

javascript - 在哪里重置计算器中运算符的值?

Haskell:需要计算器程序的启发

ruby - 涉及逆波兰计算器的正则表达式问题

java - 陷入解析 JSON 的困境

java - 按钮 onClickListener 在 Android 中无法播放声音

java - getApplicationContext() 在 Application 类中返回 null