2013-03-20 185 views
3

我發現相當多的類似的問題,但主要是關於正則表達式和不正是我想做的事情。循環通過嵌套括號內容

Given a string = "(content4(content3(content2(content1...)))) 

我想首先得到葉括號內容(內容1 ...)除上述內容2(內容2(內容1 ...))比上面一個新的水平..一個水平等。我有幾個非常複雜的解決方案,但我不知道是否沒有更簡單的方法。這似乎是最好的遞歸解決,但我無法找到一個好的解決方案呢。 有人也許已經解決已經類似的東西。 你們是否有任何意見或建議?

THX在您的幫助,我很感激

此外:

的字符串也可以是這樣的:

字符串=「(content4(content3(內容2(內容1 ... ); content5(content6 ...))))」

+0

它看起來像一個正常的堆棧probelm對我來說。順便說一下,你的字符串缺少一個'''。 – cwhsu 2013-03-20 15:51:45

+1

恕我直言,正則表達式不合適,簡單遞歸裁剪解析器是要走的路 – 2013-03-20 15:52:26

+0

是否有更多然後一個元素內的零件? – 2013-03-20 15:53:04

回答

0

我HyperTalk,但算法的框架做了很久以前是一樣的:

1 - 每個TI我遇到一個左括號,在你的括號內加上1 2 - 做圓括號的相反事情

每次你找到第一個左括號,存儲它的位置+1,與位置1一樣關閉括號。

當右括號被發現,提取子串和遞歸就可以了。

如果你想獲得更多的嵌套的「葉子」第一,只是使用列表用括號的位置,和倒讀您的列表(或使用堆棧)。

但是那要注意:這種技術只會給你帶來的第一個孩子。

1

使用堆棧。

把你的字符串分爲3種類型的元素。

a。左括號。

灣兩個連續的左括號之間的字符串或如果沒有則第二左括號左括號和即時右括號之間的字符串。

℃。右括號

的辦法是像下面這樣。

  1. 按下左括號到堆棧的頂部。

  2. 推兩個左括號之間的串到給出的堆棧的頂部的是第二左括號確實存在,則跳轉步驟3別的推,一個左和右括號之間是在壓入堆棧和GOTO的頂部的串步驟4。

  3. 將字符串之後的左括號(兩個左括號之間的字符串)推到堆棧頂部。重複步驟1至3,直到遇到右括號。

  4. 一旦你遇到一個右括號,刪除前兩個元素是字符串(兩個左括號之間的字符串)或如適用字符串(左,立即右括號之間的字符串),並從左邊括號 堆疊並調整頂部索引和字符串索引。現在您有 的內容1.

  5. 重複第4步,直到獲得所有內容。

0

確定這裏是你的問題的一個很好的解決方案。

String str = "(content4(content3(content2(content1...))))"; 
    str = str.replaceFirst("\\(", ""); 
    String[] results = str.split("\\)")[0].split("\\("); 

    int l = results.length; 
    for (int j = 0; j < l/2; j++) { 
     String temp = results[j]; 
     results[j] = results[l - j - 1]; 
     results[l - j - 1] = temp; 
    } 

    for (String string : results) { 
     System.out.println(string); 
    } 

代碼解釋:

  • 首先我們刪除第一個「(」,因爲它會導致一個空字符串出現在年底
  • 周圍分割字符串。「)」,並採取在索引0的字符串,以保持我們的數據:

    該字符串應該是這樣的,現在:

content4(content3(內容2(內容1 ...

  • 然後通過再次分裂左右 「(」 我們得到了我們的內容安排在背面。
  • 我們終於扭轉陣列
1

這似乎與理智的投入相當不錯的工作。我還沒有測試過奇怪的。

public static void main(String args[]) { 
    ArrayList<String> split = split("(content4(content3(content2(content1...))))"); 
    System.out.println("Split: " + split); 
} 

// Standard set of braces. 
private static final String openBraces = "({[<"; 
// Matching close set. 
private static final String closeBraces = ")}]>"; 

public static ArrayList<String> split(String s) { 
    // Default to splitting with my standard set of braces. 
    return split(s, openBraces, closeBraces); 
} 

// Holds the start of an element and which brace started it. 
private static class Start { 
    // The brace number from the braces string in use. 
    final int brace; 
    // The position in the string it was seen. 
    final int pos; 

    // Constructor. 
    public Start(int brace, int pos) { 
    this.brace = brace; 
    this.pos = pos; 
    } 

    @Override 
    public String toString() { 
    return "{"+openBraces.charAt(brace)+","+pos+"}"; 
    } 
} 

public static ArrayList<String> split(String s, String open, String close) { 
    // The splits. 
    ArrayList<String> split = new ArrayList<String>(); 
    // The stack. 
    ArrayList<Start> stack = new ArrayList<Start>(); 
    // Walk the string. 
    for (int i = 0; i < s.length(); i++) { 
    // Get the char there. 
    char ch = s.charAt(i); 
    // Is it an open brace? 
    int o = open.indexOf(ch); 
    // Is it a close brace? 
    int c = close.indexOf(ch); 
    if (o >= 0) { 
     // Its an open! Push it. 
     stack.add(new Start(o, i)); 
    } else if (c >= 0 && stack.size() > 0) { 
     // Pop (if matches). 
     int tosPos = stack.size() - 1; 
     Start tos = stack.get(tosPos); 
     // Does the brace match? 
     if (tos.brace == c) { 
     // Matches! 
     split.add(s.substring(tos.pos, i+1)); 
     // Done with that one. 
     stack.remove(tosPos); 
     } 
    } 
    } 
    return split; 
} 

打印:

Split: [(content1...), (content2(content1...)), (content3(content2(content1...))), (content4(content3(content2(content1...))))] 
0

這裏去我的方式通過設置支柱的兩側頭部和尾部標誌來解決這個問題,但真正的經典方法是使用堆棧。

public static void main(String[] argv) { 
    String str = "(content4(content3(content2(content1...))))"; 
    int head = str.lastIndexOf("("); 
    int tail = 0; 

    while (head != -1) { 
     // stop loop if the brace mismatch 
     if (str.substring(tail, str.length()).indexOf(")") == -1) 
      break; 
     tail += str.substring(tail, str.length()).indexOf(")") + 1; 
     String res = str.substring(head, tail); 
     System.out.println(res); 
     head = str.substring(0, head).lastIndexOf("("); 

    } 
}