3

私はかなり多くの同様の質問を見つけましたが、ほとんどが正規表現に関するものであり、正確にやりたいことではありません。

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

最初に葉括弧のコンテンツ (content1...) を content2 の 1 つ上のレベル (content2(content1...)) より上の次のレベルよりも取得したいと思います..など。本当に複雑な解決策がいくつかありますが、もっと簡単な方法はないのでしょうか。これは再帰的に解決するのが最善のようですが、まだ良い解決策を見つけることができません。誰かがすでに似たようなことを解決しているかもしれません。アイデアや提案はありますか?

あなたの助けを事前にthx、感謝します

添加 :

文字列は次のようにもなります。

文字列 = "(content4(content3(content2(content1...);content5(content6...))))"

4

5 に答える 5

3

スタックを使用します。

文字列を 3 種類の要素に分割します。

a. 左括弧。

b. 2 つの連続する左括弧の間の文字列、または 2 番目の左括弧がない場合は、左括弧とすぐ右の括弧の間の文字列。

c. 右括弧

アプローチは次のようなものになります。

  1. 左括弧をスタックの一番上にプッシュします。

  2. 2 番目の左括弧が存在する場合、2 つの左括弧の間の文字列をスタックの一番上にプッシュし、ステップ 3 に進みます。そうでない場合は、左括弧と右括弧の間の文字列をスタックの一番上にプッシュし、ステップ 4 に進みます。

  3. 文字列 (2 つの左括弧の間の文字列) の後の左括弧をスタックの一番上にプッシュします。右括弧が現れるまで、手順 1 ~ 3 を繰り返します。

  4. 右括弧が見つかったら、スタックから文字列 (2 つの左括弧の間の文字列) または該当する場合は文字列 (左括弧と右括弧の間の文字列) と左括弧である上位 2 つの要素を削除し、トップ インデックスを調整します。および文字列インデックス。これでコンテンツ 1 ができました。

  5. すべてのコンテンツを取得するまで、手順 4 を繰り返します。

于 2013-03-20T15:59:42.363 に答える
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...))))]
于 2013-03-20T16:52:56.223 に答える
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...

  • 次に、「(」の周りで再び分割することで、コンテンツを逆に配置します。
  • 最後に、配列を逆にします
于 2013-03-20T16:18:31.767 に答える
0

私はずっと前に HyperTalk でそれを行いましたが、アルゴリズムのフレームは同じままです:

1 - 開き括弧に遭遇するたびに、括弧カウンターに 1 を追加します 2 - 閉じ括弧に対して逆のことを行います

最初の開き括弧を見つけるたびに、その位置 + 1 を保存し、閉じ括弧の位置 -1 で同じことを行います。

閉じ括弧が見つかったら、部分文字列を抽出して再帰します。

よりネストされた「葉」を最初に取得したい場合は、括弧の位置でリストを使用し、リストを逆方向に読み取ります (またはスタックを使用します)。

ただし、注意してください。この手法では最初の子しか生まれません。

于 2013-03-20T15:52:22.453 に答える
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("(");

    }
}
于 2013-03-20T17:18:43.410 に答える