java 检查串是否平衡

qyswt5oh  于 2023-02-11  发布在  Java
关注(0)|答案(5)|浏览(154)

我想检查一个字符串是否与递归平衡。我在论坛上找到了一些与这个问题相关的帖子,有些答案是用我不懂的编程语言写的。我可以在堆栈溢出上阅读类似的问题后用堆栈做,我如何递归地做?

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 
}

平衡是{}()[]及其任意组合,如[()]
我不希望任何人为我编码,事实上,我希望知道如何做它。这就是为什么我不理解其他语言的答案,因为他们太具体的语言,而不是一个算法。

wsxa1bj1

wsxa1bj11#

这是一个算法,我刚刚试过了,它很有效。想法是在每个开括号上你都期望有一个相同类型的结束括号。上面的函数需要像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);

}

下面是非堆栈版本的代码:Call是这样的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;
}
xytpbqjk

xytpbqjk2#

递归的原理和使用堆栈的原理是一样的,调用堆栈是LIFO结构,你可以根据它进行调用。
举一个简单的平衡字符串:

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

重要的事先说-我们先定好条件。

  • 我们不关心圆括号、大括号和方括号以外的字符,我们可以忽略这三个字符以外的字符。
  • 如果我们遇到圆括号、大括号或方括号,我们会立即递归并在字符串的其余部分搜索匹配项,也就是说,如果我从bal开始,我会在bal.substring(1)上递归。

我不会使用循环,因为你仍然在遍历整个String,我宁愿消耗它,以减少我必须回溯的字符数量。

enyaitl3

enyaitl33#

直接循环是快速解决方案:

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),不含子串等。

vecaoik1

vecaoik14#

让我们正式地处理这个问题,以增加我们不需要大量调试就能得到一个工作解决方案的可能性。
什么是平衡字符串?下面是一个简单的语法:

BalancedString: Sequence end-of-string;

Sequence:
    Fragment Sequence |
    (* empty *);

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

请注意,此语法生成类似(hello)[[good]{bye}]的字符串,它们具有多个“顶级”组。
现在让我们把它变成一个递归下降解析器,每个非终结符(BalancedStringSequenceFragment)都变成一个函数,我们从解析'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。我们将从它的三个类似结果中提取公共代码到一个helper函数中。

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;
    }
}

helper函数期望接收到打开器的偏移量,以便在失败时返回该偏移量;如果成功,则返回刚刚经过关闭器的偏移量。

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;
    }
}
olhwl3o2

olhwl3o25#

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/ .

相关问题