2015-11-05 68 views
0

我有一個方法,它應該驗證在使用java的字符串中準確打開和關閉括號。這個方法將被用來解析數學表達式,所以對括號進行平衡很重要。出於某種原因,它在這兩個運行的返回false:無法正確驗證java方法中的平衡括號解析

System.out.println(parChecker("(()")); // returns false :-) 
System.out.println(parChecker("((()))")); // returns false :-( WHY?? 

下面是一個使用棧來解決問題的方法。有些事情是錯誤的,因爲它也是一個平衡的括號。有什麼問題?先謝謝你。

public static boolean parChecker(String str) { 
    String[] tokens = str.split(""); 
    int size = tokens.length; 
    Stack theStack = new Stack(size); 
    int index = 0; 
    boolean balanced = true; 
    while ((index < size) && balanced) { 
     String symbol = tokens[index]; 
     if (symbol.equals("(")) { 
      theStack.push(symbol); 
     } else { 
      if (theStack.isEmpty()) { 
       balanced = false; 
      } else { 
       theStack.pop(); 
      } 
     } 
     index++; 
    } 

    if (balanced && theStack.isEmpty()) { 
     return true; 
    } else { 
     return false; 
    } 

} 

下面是我用我的Stack類:

public class Stack { 

    private Object [] stack; 
    private int maxSize = 0; 
    private int top; 

    public Stack(int size){ 
     maxSize = size; 
     stack = new Object[maxSize]; 
     top = -1; 
    } 

    public void push(Object obj){ 
     top++; 
     stack[top] = obj; 
    } 

    public Object pop(){ 
     return stack[top--]; 
    } 

    public Object peek(){ 
     return stack[top]; 
    } 

    public boolean isEmpty(){ 
     return (top == -1); 
    } 

    public boolean isFull(){ 
     return (top == maxSize -1); 
    } 
} 
+0

爲什麼不要只用調試它? – manouti

+0

如果您確實想要解析算術表達式,請創建一個語法。根據語法,創建一個解析器,它將爲您提供一個抽象語法樹。您可能想了解一些基本的編譯器技術。如果你一直這樣做,你的代碼會變得混亂,我保證它。 – Turing85

+0

我的目標是學習使用堆棧數據結構。這是它的一個用處。否則,我不關心解析器。讓我們回到這個問題。任何想法爲什麼它返回一個錯誤? – Doublespeed

回答

6

眼前的問題是這樣的

String[] tokens = str.split(""); 

給你第一個字符= 「」 如果你使用java 1.7以下,所以你會退出你的循環,因爲堆棧是空的...

注意:這已在java 1.8split difference between java 1.7 and 1.8

變化:

char[] tokens = str.toCharArray(); 

然而,我想,你需要考慮的是,有可能在你的第一(是字符,而您可能有其他字符,然後()

+0

嗯?不,這不是問題。拆分字符串將返回String中的一組令牌。 – Doublespeed

+0

此外,您不能將'char []'賦值給'String []'。 – Kenney

+1

@Doublespeed請使用'System.out.println(Arrays.toString(tokens))')查看分割的結果。 Peter Friberg說得對。 – RealSkeptic

3

據我所知,代碼沒有問題(證明這是一個Java 7特定問題。))。

我想,雖然提供了一個替代方法,用於教育目的,就是短,並且是寬容的其他人物存在:

public static boolean parChecker(String str) { 
    Stack stack = new Stack(str.length()); 
    for (char c : str.toCharArray()) 
     switch (c) { 
     case '(': 
      stack.push(c); 
      break; 
     case ')': 
      if (stack.isEmpty() || stack.pop() != Character.valueOf('(')) 
       return false; 
     } 
    return stack.isEmpty(); 
} 

按照要求,這裏是另一種解決方案是不使用堆棧:

public static boolean parChecker(String str) { 
    str = str.replaceAll("[^()]", ""); 
    while (str.contains("()")) 
     str = str.replace("()", ""); 
    return str.isEmpty(); 
} 

還有一對道路:@ FredK的算法:

public static boolean parChecker(String str) { 
    int depth = 0; 
    for (char c : str.toCharArray())  
     if ((depth += c == '(' ? 1 : c == ')' ? -1 : 0) < 0) 
      return false; 
    return depth == 0; 
} 
+0

爲肯尼投票..我的主要是調試答案,即使有些問題存在; ) –

+0

謝謝!我提高了這一點。但@Petter你指出了我的代碼到底是什麼問題,並揭示了string.split的螺絲。所以我不得不接受你的答案。但是這個答案是處理代碼的好方法。 – Doublespeed

+0

@PetterFriberg謝謝!你也值得你的選票,因爲你的努力!雖然,我一直無法獲得一個空字符串:'for(String s:「()」。split(「」)) \t \t \t System.out.println(s);' – Kenney