2013-03-20 2 views
3

Я нахожу довольно много подобных вопросов, но в основном касаюсь регулярного выражения, а не точно, что я хочу делать.цикл через вложенные круглые скобки

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

Я хотел бы получить содержание листьев скобку первой (Content1 ...), чем на один уровень выше Content2 (Content2 (Content1 ...)), чем на следующий уровень выше .. и так далее. У меня есть несколько действительно сложных решений, но мне интересно, не намного ли проще. Кажется, это лучше всего рекурсивно решено, но я пока не нашел хорошего решения. Кто-то, возможно, решил уже что-то подобное. У вас есть идеи или предложения?

ТНХ заранее за вашу помощь, я ценю это

Сложение:

Строка может также выглядеть следующим образом:

строка = «(content4 (content3 (Content2 (Content1 ...); content5 (content6 ...))))»

+0

Для меня это выглядит как обычная пробная проблема. Кстати, в вашей строке отсутствует '' '. – cwhsu

+1

IMHO regexp не подходит, простой рекурсивный достойный парсер - это способ пойти –

+0

Нет ли еще одного элемента внутри parens? –

ответ

0

Я сделал это давно с HyperTalk, но алгоритмической кадра остается неизменным:

1 - каждый ти я столкнулся с открывающей скобкой, добавьте 1 в счетчик скобок 2 - сделайте обратную вещь для закрытия круглых скобок

Каждый раз, когда вы узнаете первую открывающую скобку, сохраните ее положение + 1, сделайте то же самое с позицией-1 для закрытия круглых скобок.

Когда закрывающая скобка найдена, извлеките подстроку и запишите ее.

Если вы хотите сначала получить более вложенный «лист», просто используйте списки с положением скобок и прочитайте свой список назад (или используйте стек).

Но остерегайтесь этого: эта техника принесет вам только первого ребенка.

1

Используйте стопку.

Разделите свою строку на 3 типа элементов.

a. левая скобка.

b. Строка между двумя последовательными левыми скобками или если нет вторых левых скобок, тогда строка между левой скобкой и непосредственной скобкой справа.

c. правая скобка

Подход будет примерно следующим.

  1. Нажмите левую скобку на вершине стека.

  2. нажимаем строку между двумя левыми скобками на верхнюю часть стека, учитывая, что вторая левая скобка существует, а затем шаг 3 еще толкает строку, которая находится между левой и правой скобками на вершине стека и переходит step4.

  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 (Content2 (Content1 ...

  • Затем, разделив снова вокруг "(" мы получаем наш контент расположены в обратном порядке.
  • наконец мы поменяем массив со
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("("); 

    } 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^