技巧:
递归顺序 10进制 快速幂
思路:
1. 可能出现多余的括号 但是不会出现错误的括号. 例如
---多余的括号---
a: ((1 + 1) || ((1 + 1))))
b: ((((1 + 1))))
c: 1 + (1
---错误的括号---
a: 1 + )1
2. (关于运算顺序和办法)运算符优先顺序 由低到高排序为 (+,-) (* /) ^
由于递归特性 如果表达式中运算符存在的情况下 。例如扫到了+和* 我们要先算加法。原因是最先进入递归的最后才能返回-对应上了优先度.
3. (关于多余括号的处理和一些其他情况)
case1 (1 + 1) 或 (1 + 1 或 1 + 1) ======> 由于cnt 不可能是0 所以在这里需要按照情况拿掉多余的括号再次调用递归函数
case2 123456 ======> 纯数字的话直接返回即可
实现:
package main
import (
. "fmt"
"io"
"bufio"
"os"
"math"
)
// a 的 b次方
func power(a, b int) int {
return int(math.Pow(float64(a),float64(b)))
}
func number(s string, l, r int) int {
ans := 0
for i := 0; r - i >= l; i++ {
ans += int(s[r - i] - '0') * power(10, i)
}
return ans
}
func cale(s string, l, r int) int {
var cnt, opt1, opt2, opt3 int
for i := l; i <= r; i ++{
if s[i] == '(' {
cnt++
}else if s[i] == ')' {
cnt --
}else if cnt == 0 {
if s[i] == '+' || s[i] == '-' {
opt1 = i
}else if s[i] == '*' || s[i] == '/' {
opt2 = i
}else if s[i] == '^' {
opt3 = i
}
}
}
// 排除多余的括号
if cnt > 0 && s[l] == '(' {
return cale(s, l + 1, r)
}else if cnt < 0 && s[r] == ')' {
return cale(s, l, r - 1)
}else if (opt1 | opt2 | opt3) == 0 {// 无运算符
// 拿掉括号
if s[l] == '(' && s[r] == ')' {
return cale(s, l + 1, r - 1)
}
return number(s, l, r)
}
// 递归求解
if opt1 > 0 {
if s[opt1] == '+' {
return cale(s, l, opt1 - 1) + cale(s, opt1 + 1, r)
}
return cale(s, l, opt1 - 1) - cale(s, opt1 + 1, r)
}else if opt2 > 0 {
if s[opt2] == '*' {
return cale(s, l, opt2 - 1) * cale(s, opt2 + 1, r)
}
return cale(s, l, opt2 - 1) / cale(s, opt2 + 1, r)
}else {
return power(cale(s, l, opt3 - 1), cale(s, opt3 + 1, r))
}
}
// https://ac.nowcoder.com/acm/problem/50999
func NC50999(_r io.Reader, _w io.Writer) {
in, out := bufio.NewReader(_r), bufio.NewWriter(_w)
defer out.Flush()
var s string
Fscan(in, &s)
Fprintln(out, cale(s, 0, len(s) - 1))
}
func main() {
NC50999(os.Stdin, os.Stdout)
}

京公网安备 11010502036488号