C 平衡圆括号-堆栈是必需的吗?
如果我想检查字符串的有效括号用法,我可以使用以下简单代码:C 平衡圆括号-堆栈是必需的吗?,c,algorithm,C,Algorithm,如果我想检查字符串的有效括号用法,我可以使用以下简单代码: int counter = 0; for(int i = 0; i < length_of_string; i++){ if(string[i] == '(' ) counter++; else if(string[i] == ')' ) // string is a char array counter--; if(counter < 0) retur
int counter = 0;
for(int i = 0; i < length_of_string; i++){
if(string[i] == '(' )
counter++;
else if(string[i] == ')' ) // string is a char array
counter--;
if(counter < 0)
return -1; // error because the ')' should come AFTER '('
}
if(counter == 0)
return 0; // the string is OK
else
return -1; // unbalanced
int计数器=0;
for(int i=0;i<字符串的长度;i++){
如果(字符串[i]=='(')
计数器++;
else if(string[i]==')//string是一个字符数组
计数器--;
如果(计数器<0)
return-1;//错误,因为“%”应该在“(”后面
}
如果(计数器==0)
返回0;//字符串正常
其他的
返回-1;//不平衡
我的问题是-我认为这段代码做得很好,但我见过一些使用堆栈的实现。这是为什么?使用堆栈是否能让我处理更复杂的情况?使用
堆栈非常容易理解,而且效率也很高。这是因为当您看到时,您可以将推送到堆栈中一个开始标记((
)和当您看到一个结束标记()
)时的弹出标记()。这与使用计数器的代码非常相似
要检查带括号的字符串是否合法,只需返回is_stack_empty(my_stack);
(或其任何变体)即可得到结果
注:诚然,正如人们所说,在这里使用堆栈可能不是一个好办法,因为计数器可以完美地完成这项工作。但是如上所述,堆栈
可以很好地处理数学表达式,例如可以有多种类型标记的表达式((),[],{}
).如果您只想检查不匹配的括号,则不需要创建堆栈,代码也很好。如果您想解析表达式(例如数学表达式),则肯定需要一个字符堆栈来推送运算符和括号。请阅读。如果只是为了平衡括号,则使用堆栈具有以下优点:
- 您可以将用户指向未闭合圆括号的偏移量
- 您可以平衡不同类型的分组运算符,例如
[]
、{}
和()
,并验证它们是否正确嵌套
请注意,如果要支持字符串、字符、正则表达式文字和可能的注释,可能需要更仔细地分析字符串。以下是使用堆栈的Java代码,它可以帮助您平衡多个括号
public boolean isValid(String s) {
HashMap<Character, Character> closeBracketMap = new HashMap<Character, Character>();
closeBracketMap.put(')', '(');
closeBracketMap.put(']', '[');
closeBracketMap.put('}', '{');
HashSet<Character> openBracketSet = new HashSet<Character>(
closeBracketMap.values());
Stack<Character> stack = new Stack<Character>();
char[] chars = s.toCharArray();
for (int i = 0; i < chars.length; i++) {
char cur = chars[i];
if (openBracketSet.contains(cur)) {
stack.push(cur);
} else { // close brackets
if (stack.isEmpty()) {
return false;
}
if (closeBracketMap.get(cur) != stack.peek()) {
return false;
}
stack.pop();
}
}
return stack.isEmpty();
}
这意味着我们将逐个删除支架。
例如:字符串s=“”(leng=10;s.length()=10)它将删除“[]”、“[]”、“()”
然后s=“({})”(s.length()=4)它将继续删除“{}”
然后s=“()”(s.length()=2),它将继续删除“()”
然后s=“”(s.length()=0)。它将中断循环,因为((len==10)!=(s.length()=0))
然后我们就可以检查它是否正确了。:)对不起,我不明白你的问题。你是在问为什么有些人用堆栈来解决这个问题,而有些人没有?另外,你所说的堆栈到底是什么意思?对于这种特定的情况,似乎不需要堆栈。但是,如果结构更复杂,则需要保存上下文,这是堆栈解决的问题。例如,如果您同时有圆括号()
和方括号[]
,并且您希望确保它们正确嵌套,那么简单地计算它们将不再足够。不,这不会检查正确的嵌套。考虑<代码>([)] < /代码>。这应该是一个错误。但是您的简单计数器解决方案无法将其与([])
区分开来。您可以将计数器视为一种退化堆栈—您唯一可以推动它的是(
s,所以您只需要知道堆栈有多深。所以++
是推送操作,--
是弹出操作,什么是myStack.Empty()
?当然不是。但最重要的是你需要阅读问题,这并不能回答问题。我不同意。我的回答解决了问题,并解释了人们为什么选择使用堆栈。正如我所说的,我知道空()如果不是c,您可以使用任何其他遵循此逻辑的函数,这非常简单。顺便说一句:我认为OP知道如何使用堆栈。
public class Groups{
public static boolean groupCheck(String s) {
int len;
do {
len = s.length();
s = s.replace("()", "");
s = s.replace("{}", "");
s = s.replace("[]", "");
} while (len != s.length());
return s.length() == 0;
}
}