LeetCode 的奇怪 Bug 记录
题目不重要,就是今天的每日一题,把数学计算转换成树然后求值即可。
题解满天飞,而且大思路有的情况下,动手画一画应该就行。
重点在于发现了 LeetCode 的一个奇怪的 Bug
在本地调试时,测了很多组奇怪的数据,全部通过了,但是在 LeetCode 上却被一个并不奇怪的数据卡掉了。
但是本地测又完全没有问题,所以尝试通过调试输出查看问题,最后发现了一个更奇葩的情况
添加一个无意义的输出,会导致结果正确
简单描述下就是,本地跑、Go 官方的在线环境跑,都没有问题;在 LeetCode 上跑,结果不对,但是加了一个fmt.Print()
,结果却又对了。
而显然fmt.Print()
在代码里毫无意义,不应该影响就结果
代码如下,可以在 LeetCode 在线环境里测试。
package main import "fmt" type OpTree interface { Calc() int Debug() string } type Number struct { num int } func NewNumber(num int) *Number { return &Number{ num: num, } } func (t *Number) Calc() int { if t == nil { return 0 } return t.num } func (t *Number) Debug() string { if t == nil { return "" } return fmt.Sprint(t.num) } type Operator struct { L OpTree R OpTree Op byte tempOp byte } func (t *Operator) Calc() (res int) { if t == nil { return 0 } var l, r int if t.L != nil { l = t.L.Calc() } if t.R != nil { r = t.R.Calc() } switch t.Op { case '+': res = l + r case '-': res = l - r case '*': res = l * r case '/': res = l / r default: res = l } // fmt.Printf("%d %c %d = %d\n", l, t.Op, r, res) return res } func (t *Operator) Debug() string { if t == nil { return "" } l := "" r := "" if t.L != nil { l = t.L.Debug() } if t.R != nil { r = t.R.Debug() } return fmt.Sprintf("(%s) %c (%s)", l, t.Op, r) } func (t *Operator) Insert(nt OpTree, op byte) *Operator { if t == nil { t = new(Operator) } // ??? // fmt.Print() if t.L == nil { t.L = nt t.Op = op return t } else if t.R == nil { t.R = nt t.tempOp = op return t } // 两侧都已满 root := &Operator{ L: t, R: nt, Op: t.tempOp, tempOp: op, } return root } func Parse(s string, start, n int) (root *Operator, idx int) { root = new(Operator) var temp *Operator = nil num := 0 hasNum := false getLeft := func() (left OpTree) { if hasNum { left = NewNumber(num) num = 0 hasNum = false } if temp != nil { if left != nil { temp = temp.Insert(left, '[') } left = temp temp = nil } return } defer func() { root = root.Insert( getLeft(), ']', ) // if root.R == nil { // root = root.L.(*Operator) // } }() for i := start; i < n; i++ { switch s[i] { case '(': temp, i = Parse(s, i+1, n) case ')': return root, i case '+', '-': root = root.Insert( getLeft(), s[i], ) case '*', '/': temp = temp.Insert( getLeft(), s[i], ) case ' ': continue default: // 数字 hasNum = true num = num*10 + int(s[i]-'0') } } return root, n } func calculate(s string) int { n := len(s) root, _ := Parse(s, 0, n) fmt.Println(root.Debug()) return root.Calc() } func main() { // fmt.Println(calculate("0")) // fmt.Println(calculate("(1+2)*3")) // fmt.Println(calculate("1+2+3*4*5+6+(7+8)*9+10")) fmt.Println(calculate("1*2*3")) }
已反馈给官方 #14618 工单 Go 语言执行结果存在问题