2013-03-20 151 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("("); 

    } 
}