小甲鱼动手题难以理解
s = input("请输入测试字符串:")stack = []
for c in s:
if c == '(' or c == '{' or c == '[':
stack.extend(c)
else:
if len(stack) == 0:
print("非法")
break
if c == ')':
d = '('
elif c == ']':
d = '['
elif c == '}':
d = '{'
if d == stack[-1]:
stack.pop()
else:
print("非法")
break
else:
if len(stack) != 0:
print('非法')
else:
print("合法")stack.extend(c)
这题是 小甲鱼的动手题 我一直不明白 我输入{}为什么是合法的,当最开始的if语句成立的时候stack.extend(c) 录入的不应该是c里面从s里面提取的{}吗然后c里面就有了{},然后stack里面就被录入了{},那么这里面就有了左括号和右括号,那么在下面的 if d == stack[-1] 语句中不应该是不成立的吗,d是{ 而stack[-1]是} 所以这两个不应该相等啊 应该直接跳到下一个else语句里面去判断为非法了呀?有大佬指点一下我的错误理解吗 本帖最后由 sfqxx 于 2023-4-9 15:57 编辑
在这段代码中,当遇到左括号时,它们被添加到栈(stack)中。例如,当输入是 `{}` 时,`{` 首先被添加到栈(stack)中。然后,当 `}` 出现时,将其与栈顶元素进行比较,如果两者匹配,则将栈顶元素弹出。在这种情况下,栈顶元素是 `{` ,因此代码执行 `stack.pop()` 操作来删除 `{`。这样,最终的栈(stack)是空的,因此字符串是合法的。
事实上,这个程序实现了一个简单的括号匹配算法,可以用于检查输入的字符串中的括号是否正确匹配。在这里,`{}` 是一个合法的字符串,因为它们是成对出现的,并且左括号先出现,右括号后出现,并且它们在栈(stack)中被正确地匹配和弹出。 本帖最后由 isdkz 于 2023-4-9 15:59 编辑
您好!这段代码的主要目的是检测输入的字符串中的括号是否合法,即括号是否成对出现和正确匹配。
这里有一个关键点:stack.extend(c) 实际上是将字符串 c 的每个字符逐个添加到 stack 中。
当输入为 {} 时,遇到 { 时,stack.extend(c) 将 { 添加到 stack。然后,遇到 } 时,
代码会判断它是否匹配 stack 中的最后一个元素(即 {),如果匹配,就将其从 stack 中删除。
这里是代码的简化版以帮助您理解:
s = input("请输入测试字符串:")
stack = []
for c in s:
if c == '(' or c == '{' or c == '[':
stack.append(c)# 使用append替代extend
else:
if len(stack) == 0:
print("非法")
break
if c == ')':
d = '('
elif c == ']':
d = '['
elif c == '}':
d = '{'
if d == stack[-1]:
stack.pop()
else:
print("非法")
break
else:
if len(stack) != 0:
print('非法')
else:
print("合法")
当您输入 {} 时,stack 中的元素变化如下:
[*]{ -> stack = [{]
[*]} -> stack = []
在遍历字符串的过程中,遇到 { 时,将其添加到 stack,遇到 } 时,发现它匹配 stack 中的最后一个元素 {,因此将其从 stack 中删除。最后,stack 为空,表示括号是合法的。 for c in s:
if c == '(' or c == '{' or c == '[':
stack.append(c)
如果说一开始这里就成立了 为什么不是直接把{}都录入进stack呢 而是先把{录入进去再判断}判断}是否为栈顶元素不应该是后面要做的事吗 最开始这里不应该是把{}录入进去stack吗? lhy12343 发表于 2023-4-9 16:06
for c in s:
if c == '(' or c == '{' or c == '[':
stack.append(c)
你的疑惑是非常合理的,让我来为你解答一下。
首先,对于输入字符串为{}的情况,程序的输出应该是“合法”的。原因是,这个字符串里面只有一个左括号和一个右括号,并且它们是配对的并且顺序正确,因此它是一个合法的表达式。那么在程序运行过程中,当读入{的时候,它会被加入到stack中,此时栈顶元素就是它本身;接着读入}的时候,判断后发现它的配对左括号是{,也就是当前栈顶元素,于是就弹出栈顶元素。经过这两步处理之后,stack为空,说明这个表达式是合法的。
其次,对于extend和append的使用,它们的区别在于前者接受一个可迭代对象作为参数,而后者接受一个元素作为参数。对于上面这段代码中的extend方法,它实际上是把字符串中的每一个字符都拆分开来,然后逐个加入到stack中。如果你希望把整个字符串作为一个元素添加到stack中,可以使用append方法。
希望我的回答能够帮助你理解这段代码的运行过程。
https://t3.wodetu.cn/2023/04/08/7408df3fbffa9f5551168a8d38de45d5.png lhy12343 发表于 2023-4-9 16:06
for c in s:
if c == '(' or c == '{' or c == '[':
stack.append(c)
这个 for 循环是逐个遍历输入字符串 s 中的字符。for c in s 是一个逐个检查输入字符串中的每个字符的循环。所以,当遇到字符 { 时,它会首先将 { 添加到 stack。然后,循环会继续检查下一个字符,即 }。这个过程是逐个处理字符,而不是一次性处理整个字符串。
让我们详细地看一下输入为 {} 时循环的执行顺序:
[*]for c in s:遍历输入字符串 s 中的每个字符。
[*]当 c 是 { 时,将 { 添加到 stack。这时,stack = [{]。
[*]循环继续,c 变为 }。这时,程序会判断这个右括号是否匹配 stack 中的最后一个元素(也就是栈顶元素)。
[*]发现 { 和 } 是匹配的,所以将 { 从 stack 中删除。这时,stack 变为空:stack = []。
[*]循环结束后,stack 为空,说明所有的括号都正确地配对了,所以输出 "合法"。
这个算法的关键在于逐个处理输入字符串中的字符。当遇到左括号时,将其添加到 stack;当遇到右括号时,检查它是否与 stack 中的最后一个元素(栈顶元素)匹配。 isdkz 发表于 2023-4-9 16:10
这个 for 循环是逐个遍历输入字符串 s 中的字符。for c in s 是一个逐个检查输入字符串中的每个字符的循 ...
懂了谢谢大佬 一切的问题就是出在for循环这里原来for循环是逐个处理 谢谢大佬 lhy12343 发表于 2023-4-9 16:20
懂了谢谢大佬 一切的问题就是出在for循环这里原来for循环是逐个处理 谢谢大佬
不客气{:5_110:}
页:
[1]