我想检查字符串是否与递归平衡。我在论坛上发现了与此问题相关的一些其他帖子,一些答案是我不懂的编程语言。在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:是平衡的是{}()[]及其任何组合,例如[()]
答案 0 :(得分:3)
使用递归执行此操作的想法与使用堆栈的原理相同。 调用堆栈是你的LIFO结构,你可以按照它进行调用。
采用简单的平衡字符串:
String bal = "(This is (perfectly) balanced.)";
首先要做的是 - 让我们建立条件。
bal
开始,我就会在bal.substring(1)
进行推算。我不会使用循环,因为你仍然遍历整个String。我宁愿消耗它,以减少我必须回溯的字符数量。
答案 1 :(得分: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;
}
答案 2 :(得分: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)没有子串等。
答案 3 :(得分:0)
让我们正式接近这一点,以增加我们在没有大量调试的情况下提出可行解决方案的可能性。
什么是平衡字符串?这是一个简单的语法:
BalancedString: Sequence end-of-string;
Sequence:
Fragment Sequence |
(* empty *);
Fragment:
'(' Sequence ')' |
'[' Sequence ']' |
'{' Sequence '}' |
any-character-not-in-'()[]{}';
请注意,此语法会生成(hello)[[good]{bye}]
之类的字符串,其中包含多个&#34;顶级&#34;基。
现在让我们把它变成一个递归下降的解析器。每个非终结符(BalancedString
,Sequence
和Fragment
)都会成为一个函数。我们将从解析&#39; BalancedString&#39;的函数开始。非末端:
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
。我们将其三个相似产品中的公共代码提取到辅助函数中。
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;
}
}
答案 4 :(得分: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");
}
}
}
}}