题解 | #四则运算#

四则运算

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)

全部评论

相关推荐

09-27 00:29
东北大学 Java
伟大的麻辣烫:查看图片
阿里巴巴稳定性 77人发布 投递阿里巴巴等公司10个岗位
点赞 评论 收藏
分享
在评审的大师兄很完美:像这种一般就是部门不匹配 转移至其他部门然后挂掉 我就是这样被挂了
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务