1

文字列と再帰のバランスが取れているかどうかを確認したいと思います。この質問に関連する他の投稿をフォーラムで見つけました。いくつかの回答は、私が理解できないプログラミング言語です。Stack Overflowで同様の質問を読んだ後、スタックでそれを行うことができますが、再帰的に行うにはどうすればよいですか?

private static boolean isBalanced(String s, char match)
{
    char c;

    if(s.isEmpty())
        return true;

    for(int i = 0; i < s.length(); i++)
    {
        c = s.charAt(i); 

        if(c == '{') 
            return isBalanced(s.substring(i+1), '}');

        else if(c == '[')
            return isBalanced(s.substring(i+1), ']');

        else if(c == '(')
            return isBalanced(s.substring(i+1), ')');

        // Closing matches.
        else if(c == match)
            return true;

    }

    return 
}

助けてください。

編集:いいえ、私は誰かにそれをコーディングしてほしくありません、実際、私は代わりにそれを行う方法を知っていることを認めます。そのため、他の言語の答えは、アルゴリズムではなくその言語に固有であるため、理解できませんでした。

EDIT2:はいバランスは{}()[]と[()]などの任意の組み合わせです

4

5 に答える 5

3

再帰でそれを行うという考え方は、スタックを使用する場合と同じ原則です。呼び出しスタックはLIFO構造であり、それに応じて呼び出しを行います。

単純なバランスの取れた文字列を取ります。

String bal = "(This is (perfectly) balanced.)";

まず最初に-条件を確立しましょう。

  • パレン、ブレース、ブラケット以外のものは気にしません。これら3つのうちの1つではない文字は無視できます。
  • パレン、ブレース、またはブラケットに遭遇した場合、すぐに再帰して、文字列の残りの部分で一致するものを検索します。つまり、で始めていた場合は、でbal繰り返しbal.substring(1)ます。

あなたはまだ文字列全体をトラバースしているので、私はループを使用しません。代わりにそれを消費して、後戻りしなければならない文字の量を減らしたいと思います。

于 2013-02-19T03:47:03.443 に答える
3

これがアルゴリズムです、私はちょうど試しました、そしてそれは働きます。アイデアは、すべてのオープニングブラケットで、同じタイプのクロージングブラケットを期待するというものです。上記の関数は、このように呼び出す必要がありますisBalanced("([2+3])", 0, new Stack<Character>())。期待される文字は、を使用して維持されstackます。

public static boolean isBalanced(String s, int i, Stack<Character> expected) {
    /* end has reached and not expecting anything then break */
    if (i == s.length())
        return expected.isEmpty();

    char c = s.charAt(i);
    /* expecting something and it is a closing type */
    /* then it should match expecting type */
    if (c == '}' || c == ')' || c == ']') {
        char e = expected.isEmpty() ? '\0' : expected.pop();
        if(e != c)
            return false;
    }

    if(c == '{') 
        expected.push('}');
    else if(c == '[')
        expected.push(']');
    else if(c == '(')
        expected.push(')');

    /* call recursively with i + 1 */ 
    return isBalanced(s, i + 1, expected);

}

スタック以外のバージョンのコードは次のとおりです。呼び出しは次のようになりますisBalanced2("{[]}[()]", 0, '\0') < 0 ? false : true

public static int isBalanced2(String s, int i, char match)
{
    if(i >= s.length())
        return match == '\0' ? 0 : -1;

    char c;
    int j;
    for(j = i; j < s.length(); j++)
    {
        c = s.charAt(j); 
        /* any of the closing type */
        if(c == ']' || c == '}' || c == ')') {
            return c == match ? j : -1;
        }

        if(c == '{') 
            j = isBalanced2(s, j + 1, '}');

        else if(c == '[')
            j = isBalanced2(s, j + 1, ']');

        else if(c == '(')
            j = isBalanced2(s, j + 1, ')');

        if(j == -1)
            break;
    }

    return match != '\0' ? -1 : j;
}
于 2013-02-19T03:57:47.877 に答える
1

直接サイクルはここでの解決策です:

private static boolean isBalanced(String s)
{
    char[] chars = new char[s.length()];
    int size = 0;
    for (int i = 0; i < s.length(); i++)
    {
        char c = s.charAt(i);
        if (c == '{' || c == '(' || c == '[') chars[size++] = c;
        if (c == '}' && (size == 0 || chars[--size] != '{')) return false;
        if (c == ')' && (size == 0 || chars[--size] != '(')) return false;
        if (c == ']' && (size == 0 || chars[--size] != '[')) return false;
    }

    return true;
}

アルゴの複雑さは、部分文字列などのないO(N)です。

于 2013-02-19T08:24:00.293 に答える
0

これに正式にアプローチして、多くのデバッグを行わなくても実用的なソリューションを思い付く可能性を高めましょう。

バランスの取れた文字列とは何ですか?簡単な文法は次のとおりです。

BalancedString: Sequence end-of-string;

Sequence:
    Fragment Sequence |
    (* empty *);

Fragment:
    '(' Sequence ')' |
    '[' Sequence ']' |
    '{' Sequence '}' |
    any-character-not-in-'()[]{}';

この文法は(hello)[[good]{bye}]、複数の「トップレベル」グループを持つような文字列を生成することに注意してください。

それを再帰下降パーサーに変えましょう。各非終端記号(、、、BalancedStringおよびSequenceFragmentは関数になります。'BalancedString'非終端記号を解析する関数から始めます。

private static bool parseBalancedString(String input, int offset) {
    offset = parseSequence(input, offset);
    return offset == input.length();
}

parseSequenceこの関数は、解析を停止したオフセットを返すことを期待していることに注意してください。parseSequence次に書きましょう。直接再帰的にする代わりに、ループを使用します。

private static int parseSequence(String input, int offset) {
    bool parseSucceeded = true;
    while (parseSucceeded) {
        int newOffset = parseFragment(input, offset);
        parseSucceeded = newOffset > offset;
        newOffset = offset;
    }
    return offset;
}

parseSequenceは、解析を停止したオフセットを返すことを期待していることに注意しparseFragmentてください。失敗した場合は、渡されたオフセットを返す必要があります。今、私たちは書くでしょうparseFragment。3つの類似したプロダクションから共通のコードをヘルパー関数に抽出します。

private static int parseFragment(String input, int offset) {
    if (offset >= input.length()) {
        return offset;
    }

    switch (input.charAt(offset)) {
        case '(': return helpParseFragment(input, offset, ')');
        case '[': return helpParseFragment(input, offset, ']');
        case '{': return helpParseFragment(input, offset, '}');
        default: return offset + 1;
    }
}

ヘルパー関数は、オープナーのオフセットを受け取ることを期待しているため、失敗した場合はそのオフセットを返すことができます。成功すると、クローザーを過ぎたオフセットを返します。

private static int helpParseFragment(String input, int offset, char closer) {
    int newOffset = parseSequence(input, offset + 1);
    if (newOffset > offset && newOffset < input.length() && input.charAt(newOffset) == closer) {
        return newOffset + 1;
    } else {
        return offset;
    }
}
于 2013-02-19T04:42:45.410 に答える
0
import java.util.*;
class Solution{

   public static void main(String []argh)
   {
      Scanner sc = new Scanner(System.in);


      while (sc.hasNext()) 
      {
         String input=sc.next();
         Stack<Character> stacky = new Stack<>();
          int x=0,y=0,z=0,a=0,b=0,c=0;
         for (int i = 0; i < input.length(); i++) 
         {

                switch(input.charAt(i)) 
                {
                    case '[' : a++; break;
                    case '{' : b++;break;

                     case '(' : c++;
                    break;

                    case ']' :x++; break;
                    case '}' : y++; break;

                     case ')' :
                            z++;
                    break;



                default: stacky.push(input.charAt(i));
          }


            //Complete the code

            if(x==a && y==b && z==c)
                {

                System.out.println("true");

                 }
             else
                 {
                 System.out.println("false");
             }




      }

   }
   }}

http://www.geekpandit.com/2016/07/25/simple-balanced-parenthesis-problem-stack-implementation/

于 2016-08-03T11:38:46.083 に答える