最后括号的Java递归提取,直到不再有括号

时间:2017-05-31 11:51:01

标签: java algorithm

字符串是1a2a(3a4)然后我能够提取(3a4)&计算它,让'x'成为答案然后替换主1a2ax&计算正常(这很容易,我已经完成了。(a - add,s - sub,m - mul,d - div)

对于上面的等式,我已经这样做了(仅当我有一组括号时才有效)

public class task2 {
private static double parseString(String str) {
    // declaring the operators' counters
    int a = 1;
    int s = 1;
    int m = 1;
    int d = 1;

    // splitting the string up into operands and operators
    double[] operands = Arrays.stream(str.split("[asmd]")).mapToDouble(Double::parseDouble).toArray();
    String[] operators = str.split("\\d+");

    // the rest is pretty much self-explanatory
    double total = operands[0];
    for (int i = 1 ; i < operators.length ; i++) { // note that i starts at 1 because the first item in operators
        switch (operators[i]) {                    // array is an empty string
            case "a":
                total = total * a + operands[i];
                a++;
                break;
            case "s":
                total = total * s - operands[i];
                s++;
                break;
            case "d":
                total = total * d / operands[i];
                d++;
                break;
            case "m":
                total = total * m * operands[i];
                m++;
                break;
        }
    }
    return total;
}
public static void main(String[] args){
    String x= "1a(2a6a16)a9s88s77m9d5";
    System.out.print("Expression \""+x+"\" on solving gives answer as ");

    //To extract String with Bracket
    Matcher m = Pattern.compile("\\((.*?)\\)").matcher(x);
    String y = null;
    while(m.find()) {
        y = m.group(1); 
    }
    String z = Double.toString(task2.parseString(y));
    int p = (int)Double.parseDouble(z);
    String q = Integer.toString(p);
    x = x.replaceAll("\\p{P}","");
    x = x.replace(y,q);

    // To call method to find value
    System.out.println(task2.parseString(x));
    }

}

但是当等式为

时出现概率

((1a3a(9s9s(10d200))S(10m100a(192s187))A10)d2d8)

,当我必须应用最里面的括号的递归提取,直到没有更多的括号,我正在努力。

首先(10d200)提取并计算,让答案为“P”,等式变为((1a3a(9s9sP)s(10m100a(192s187))a10)d2d8)

其次(9s9sp)提取并计算,让答案为“Q”,等式变为((1a3aQs(10m100a(192s187))a10)d2d8)

第三次(192s187)提取并计算,让答案为“R”,等式变为((1a3aQs(10m100aR)a10)d2d8)

第四次(10m100aR)提取并计算,让答案为“S”,等式变为((1a3aQsSa10)d2d8)

第五次(Td2d8)表达式计算。

Plz,帮帮我吧。提前谢谢。

2 个答案:

答案 0 :(得分:2)

伪代码:

while (there are parentheses left) {
    find first closing parenthesis;
    walk left and find nearest opening parenthesis;
    evaluate expression inbetween;
    replace expression with result and remove parentheses;
}
evaluate expression;

编辑:为了完整起见,可以使用peg.js以紧凑的方式编写:https://jsfiddle.net/mxLq9drm/2

答案 1 :(得分:1)

最简单的方法是始终解析第一对括号的内容:

stack s

for i = 0; i < len(text); i++ do
    if text[i] is openingbracket
        s.push(i)
    if next character is closing bracket
        pos = s.pop()
        res = parse(text, pos + 1, i - 1)

        text.replace(pos, i, res)  //update the string to parse
        i = pos + len(res)         //set i to the end of the newly inserted string

基本思想是将所有左括号的索引存储在堆栈中。如果遇到闭括号,请在最后一个开括号(堆栈的头部)和当前位置之间取一个字符串,计算表达式并将其替换为字符串。然后更新字符串中的当前位置并继续解析。