题解 | #四则运算#

四则运算

https://www.nowcoder.com/practice/9999764a61484d819056f807d2a91f1e

package main

import (
	"fmt"
	"strconv"
)

func isGEPriority(ch1 byte, ch2 byte) bool {
	if ch1 == '(' {
		return false
	} else if (ch1 == '+' || ch1 == '-') && (ch2 == '*' || ch2 == '/') {
		return false
	}
	return true
}

// 这里不能在方法里直接修改传入的 slice,具体原因参考下述链接
// https://www.cnblogs.com/tianwaitian/p/14961138.html
func operate(st1 []int, st2 []byte) ([]int, []byte) {
	var res int
	a, b := st1[len(st1)-2], st1[len(st1)-1]
	st1 = st1[:len(st1)-2]

	op := st2[len(st2)-1]
	st2 = st2[:len(st2)-1]

	if op == '+' {
		res = a + b
	}
	if op == '-' {
		res = a - b
	}
	if op == '*' {
		res = a * b
	}
	if op == '/' {
		res = a / b
	}

	st1 = append(st1, res)
	return st1, st2
}

func calculate(s string) int {
	var st1 []int
	var st2 []byte

	s = "(" + s + ")"

	// nextIsOp 为 true 表示为运算符
	// 无法分出减号和负号,所以使用一个 flag 标识
	nextIsOp := false

	for i := 0; i < len(s); i++ {
		if s[i] == '(' || s[i] == '[' || s[i] == '{' {
			st2 = append(st2, '(')
		} else if s[i] == ')' || s[i] == ']' || s[i] == '}' {
			for st2[len(st2)-1] != '(' {
				st1, st2 = operate(st1, st2)
			}
			// 弹出左括号
			st2 = st2[:len(st2)-1]
		} else if nextIsOp {
			for isGEPriority(st2[len(st2)-1], s[i]) {
				st1, st2 = operate(st1, st2)
			}
			// 将该运算符加入
			st2 = append(st2, s[i])
			nextIsOp = false
		} else {
			start := i
			if s[i] == '-' || s[i] == '+' {
				i++
			}
			for '0' <= s[i] && s[i] <= '9' {
				i++
			}
			n, _ := strconv.Atoi(s[start:i])
			st1 = append(st1, n)
			i--
			nextIsOp = true
		}
	}

	return st1[len(st1)-1]
}

func main() {
	var s string

	fmt.Scan(&s)
	// s := "3+2*{1+2*[-4/(8-6)+7]}"

	fmt.Println(calculate(s))
}
// 本题输入一行字符串,所以采用:fmt.Scan(&s)

全部评论

相关推荐

不愿透露姓名的神秘牛友
06-27 20:15
还能挽救吗?找同学帮忙看了一下&nbsp;字节怎么能如此对我
牛客26396789...:你这是严重红线,被发现你自己永远进不去,你那个同学直接走人,你还敢宣扬
点赞 评论 收藏
分享
06-02 15:17
门头沟学院 Java
心爱的idea:怎么会呢 应该是打招呼有问题 问就说实习6个月全国可飞随时到岗
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务