算法 表达式求值-(栈+模拟+递归回溯)

牛客网: BM49

题目: 支持加减乘及括号运算

思路: 使用栈存储每一层()内的运算结果,初始化默认运算符op='+', 字符串遍历提取连续数字, 遇到符号时停止数字提取, 匹配op进行数学运算,存储在栈中,遇到 '('符号进入下一层递归,遇到')'时求出栈中的所有数字之后进行回溯返回此层计算结果与位置索引index,所有字符串处理完时,返回的结果中取数字即可。

代码:

// go

package main
// import "fmt"

/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 * 返回表达式的值
 * @param s string字符串 待计算的表达式
 * @return int整型
*/

type Stack struct {
    data []int
}

func (s *Stack) Push(e int) {
    s.data = append(s.data, e)
}

func (s *Stack) Pop() int {
    d := s.data[len(s.data)-1]
    s.data = s.data[:len(s.data)-1]
    return d
}

func (s *Stack) IsEmpty() bool {
    return len(s.data) == 0
}

func calc(s string, index int) []int {
    stack := &Stack{}
    num := 0
    op := byte('+')
    sum := 0
    i := index
    for ; i < len(s); i++ {
        // 获取连续字符组成的数字
        if s[i] >= '0' && s[i] <= '9' {
            num = num * 10 + int(s[i] - '0')
            if i != len(s) - 1 {
                continue
            }
        }

        // 进入下一层递归
        if s[i] == '(' {
            res := calc(s, i + 1)
            num = res[0]
            i = res[i]
            if i != len(s) - 1 {
                continue
            }
        }

        // 运算符计算
        switch op {
            case '+':
            stack.Push(num)
            break
            case '-':
            stack.Push(-num)
            break
            case '*':
            stack.Push(stack.Pop()*num)
            break
        }
        // 运算完后置0
        num = 0
        if s[i] == ')' { // 结束递归回溯
            break
        } else {
            op = s[i] // 继续本层后面的运算
        }
    }
    for !stack.IsEmpty() {
        sum += stack.Pop()
    }
    return []int{sum, i}
}

func solve( s string ) int {
    // write code here
    res := calc(s, 0)
    return res[0]
}

你可能感兴趣的:(牛客网,算法刷题,表达式求值,栈,模拟,递归回溯)