2017-05-31 100 views
0

字符串是1a2a(3a4)然后我能够提取(3a4)&计算它,让'x'为答案然后替换为主1a2ax &按正常计算( (a - add,s - sub,m - mul,d - div)Java递归提取最内括号直到没有更多括号

对于上面的等式,我做了这样的工作(只适用于我有一组括号)

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,帮帮我吧。提前致谢。

+1

为什么你不显示你迄今为止做了什么? – kism3t

+0

再次嗨。那么到目前为止你尝试过了什么?在另一个问题,你已经得到了代码来评估你的表达式(https://stackoverflow.com/q/44213894/5710637) – fafl

+0

你好@fafl,我编辑thw问题的代码,当表达式有一组括号。 – mssach

回答

0

伪代码:

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; 

编辑:https://jsfiddle.net/mxLq9drm/2

+0

关于计算你的javascript代码的答案来了,但我不明白js。@fafl可以在java中提问吗? – mssach

+1

JavaScript不是Java,这个答案好像只有伪代码会好很多。如果JavaScript是用一种更通用的语言特定的方式编写的,那么这可能是一个不同的故事。 – Dukeling

+0

谢谢@fafl我得到了答案。 – mssach

1

最简单的方法是始终解析第一的内容:只是为了完整性,这可以使用peg.js写在一个紧凑的方式一对括号:

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 

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

+0

感谢@paul为新逻辑,我不知道这一点。 – mssach