Go语言实现有效括号匹配时出现索引越界(index out of range)错误的原因排查
解决Go语言实现有效括号时的索引越界错误
咱们先直接戳破问题核心——你代码里的栈顶元素索引用错了!
看报错的那行代码:arr[len(s) - 1],这里的len(s)是输入字符串的长度,但arr是咱们用来存左括号的栈,栈顶元素的索引应该是len(arr)-1,不是len(s)-1!举个实际例子:比如输入是"()",第一次循环把"("加入栈,此时len(arr)=1,而len(s)=2,len(s)-1=1,但arr只有索引0的元素,你去访问arr[1]自然就触发了index out of range的运行时错误。
另外还有个隐性问题:最后判断栈是否为空的时候,你用了reflect.DeepEqual(arr, []string{""}),这完全不对——空栈应该是长度为0的切片,不是包含空字符串的切片,这会导致原本有效的用例(比如"()")最后返回false。
下面是修正后的完整代码,我把这两处问题都修复了,还优化了一些细节:
func isValid(s string) bool { arr := make([]rune, 0) // 先判断长度是否为奇数,直接返回false,提前过滤无效用例 if len(s) % 2 != 0 { return false } // 用range遍历字符串,直接拿到字符(rune类型),避免转string的开销 for _, char := range s { if char == '(' || char == '[' || char == '{' { arr = append(arr, char) } else { // 遇到右括号时先检查栈是否为空,空栈直接不匹配 if len(arr) == 0 { return false } // 取栈顶元素做匹配判断 top := arr[len(arr)-1] if (char == ')' && top == '(') || (char == ']' && top == '[') || (char == '}' && top == '{') { arr = arr[:len(arr)-1] } else { // 括号类型不匹配,直接返回false return false } } } // 最后栈为空则说明所有括号都匹配成功 return len(arr) == 0 }
额外说下优化的细节:
- 用
rune遍历字符串,避免byte处理多字节字符的潜在问题(括号都是单字节,用byte也可,但rune更通用) - 提前判断字符串长度是否为奇数,减少不必要的循环
- 去掉冗余的
string转换,直接用字符比较,更高效 - 最后直接判断栈的长度是否为0,比用
reflect简洁且性能更好
内容的提问来源于stack exchange,提问作者Ulack
相关产品推荐
相关产品推荐

