鱼C论坛

 找回密码
 立即注册
查看: 2032|回复: 7

[已解决]小甲鱼动手题难以理解

[复制链接]
发表于 2023-4-9 15:53:58 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
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语句里面去判断为非法了呀?  有大佬指点一下我的错误理解吗
最佳答案
2023-4-9 16:10:00
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 中的最后一个元素(栈顶元素)匹配。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-4-9 15:55:41 | 显示全部楼层
本帖最后由 sfqxx 于 2023-4-9 15:57 编辑

在这段代码中,当遇到左括号时,它们被添加到栈(stack)中。例如,当输入是 `{}` 时,`{` 首先被添加到栈(stack)中。然后,当 `}` 出现时,将其与栈顶元素进行比较,如果两者匹配,则将栈顶元素弹出。在这种情况下,栈顶元素是 `{` ,因此代码执行 `stack.pop()` 操作来删除 `{`。这样,最终的栈(stack)是空的,因此字符串是合法的。

事实上,这个程序实现了一个简单的括号匹配算法,可以用于检查输入的字符串中的括号是否正确匹配。在这里,`{}` 是一个合法的字符串,因为它们是成对出现的,并且左括号先出现,右括号后出现,并且它们在栈(stack)中被正确地匹配和弹出。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-4-9 15:56:46 | 显示全部楼层
本帖最后由 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 为空,表示括号是合法的。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-4-9 16:06:32 | 显示全部楼层
for c in s:
    if c == '(' or c == '{' or c == '[':
        stack.append(c)
如果说一开始这里就成立了 为什么不是直接把{}都录入进stack呢 而是先把{录入进去再判断}  判断}是否为栈顶元素不应该是后面要做的事吗 最开始这里不应该是把{}录入进去stack吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-4-9 16:09:06 | 显示全部楼层
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方法。

希望我的回答能够帮助你理解这段代码的运行过程。

                               
登录/注册后可看大图
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

发表于 2023-4-9 16:10:00 | 显示全部楼层    本楼为最佳答案   
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 中的最后一个元素(栈顶元素)匹配。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2023-4-9 16:20:22 | 显示全部楼层
isdkz 发表于 2023-4-9 16:10
这个 for 循环是逐个遍历输入字符串 s 中的字符。for c in s 是一个逐个检查输入字符串中的每个字符的循 ...

懂了谢谢大佬 一切的问题就是出在for循环这里  原来for循环是逐个处理 谢谢大佬
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-4-9 16:21:16 | 显示全部楼层
lhy12343 发表于 2023-4-9 16:20
懂了谢谢大佬 一切的问题就是出在for循环这里  原来for循环是逐个处理 谢谢大佬

不客气
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-9-23 21:25

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表