2017-05-31 98 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