[go算法]左括号补全-双栈法

输入:1+2)*33-44)*555-666)))

输出:((1+2)*((33-44)*(555-666)))

双栈法,顾名思义,就是用两个栈来实现整个算法。一个栈保存数据,另外一个栈保存运算符。

代码实现及注释:

package main
 
import "fmt"
 
/*
    左括号补全算法
*/
 
type stackString []string
 
func (s *stackString) Push(v string) {
    *s = append(*s, v)
}
 
func (s *stackString) Pop() string {
    l := len(*s)
    if l == 0 {
        return ""
    }
    ret := (*s)[l-1]
    *s = (*s)[:l-1]
    return ret
}
 
type stackByte []byte
 
func (s *stackByte) Push(v byte) {
    *s = append(*s, v)
}
 
func (s *stackByte) Pop() byte {
    l := len(*s)
    if l == 0 {
        return 0
    }
    ret := (*s)[l-1]
    *s = (*s)[:l-1]
    return ret
}
 
func isDigit(str string, i *int) *string {
 
    if str[*i] > '0' && str[*i] <= '9' {
        var retBytes []byte
        retBytes = append(retBytes, str[*i])
        for j := *i + 1; j < len(str); j++ {
            if str[j] > '0' && str[j] <= '9' {
                retBytes = append(retBytes, str[j])
            } else {
                *i = j - 1
                ret := string(retBytes)
                return &ret
            }
        }
    }
    return nil
}
 
func isOpeartor(b byte) bool {
    switch b {
    case '+', '-', '*', '/':
        return true
    default:
        return false
    }
}
 
func main() {
    str := "1+2)*33-44)*555-666)))"
    dataS := make(stackString, 0)
    opS := make(stackByte, 0)
    for i := 0; i < len(str); i++ { // 将数字和运算符入栈
        if ret := isDigit(str, &i); ret != nil {
            dataS.Push(*ret)
        } else if isOpeartor(str[i]) {
            opS.Push(str[i])
        } else { // 取出表达式(数字)和运算符,合并,并重新入栈
            d2 := dataS.Pop()
            d1 := dataS.Pop()
            op := opS.Pop()
            exp := "(" + d1 + string(op) + d2 + ")"
            dataS.Push(exp)
        }
    }
 
    var exp string
    for j := 0; j < len(dataS); j++ {
        exp += dataS[j]
    }
 
    fmt.Println(exp)
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值