循环嵌套括号内容

时间:2013-03-20 15:48:31

标签: java loops nested parentheses

我发现了很多类似的问题,但主要是关于正则表达式而不是我想要做的事情。

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

我想首先获得叶括号内容(content1 ...),而不是上面的某个级别(content2(content1 ...)),而不是上一级...依此类推。我有一些非常复杂的解决方案,但我想知道是否有一个更简单的方法。这似乎是最好的递归解决,但我还是找不到一个好的解决方案。 有人可能已经解决了类似问题。 你们有什么想法或建议吗?

事先得到你的帮助,我很感激

附加:

字符串也可以如下所示:

string =“(content4(content3(content2(content1 ...); content5(content6 ...))))”

5 个答案:

答案 0 :(得分:2)

使用堆栈。

将您的字符串分为3种类型的元素。

一个。左括号。

湾两个连续左括号之间的字符串,或者如果没有第二个左括号,则在左括号和右前括号之间有一个字符串。

℃。右括号

方法如下。

  
      
  1. 将左括号推到堆栈顶部。

  2.   
  3. 将两个左括号之间的字符串推到堆栈顶部,因为第二个左括号确实存在然后转到第3步,否则将左右括号之间的字符串推到堆栈的顶部,转到步骤4。

  4.   
  5. 将字符串后面的左括号(两个左括号之间的字符串)推到堆栈顶部。重复步骤1到3,直到遇到右括号。

  6.   
  7. 一旦遇到右括号,请删除作为字符串的前两个元素(两个左括号之间的字符串)或者如果适用,删除字符串(左括号和右前括号之间的字符串)和左括号   从堆栈中调整顶部索引和字符串索引。现在你有了   内容1.

  8.   
  9. 重复步骤4,直至获得所有内容。

  10.   

答案 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...))))]

答案 2 :(得分:0)

我很久以前用HyperTalk做过,但算法框架保持不变:

1 - 每次遇到左大括号时,在括号中加1 2 - 关闭括号做相反的事情

每当您找到第一个左括号时,将其位置存储为+ 1,对于右括号,请执行相同的位置。

找到右括号后,提取子字符串并递归它。

如果你想首先获得更多嵌套的“叶子”,只需使用带括号位置的列表,然后向后读取你的列表(或使用堆栈)。

但请注意:这项技术只能为你带来第一个孩子。

答案 3 :(得分: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 ...

  • 然后再次分开“(”我们将内容反过来安排。
  • 最后我们反转数组

答案 4 :(得分: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("(");

    }
}