150. 逆波兰表达式求值-M-stack

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/scylhy/article/details/87654987

150. 逆波兰表达式求值-M-stack

根据逆波兰表示法,求表达式的值。

有效的运算符包括 +, -, *, / 。每个运算对象可以是整数,也可以是另一个逆波兰表达式。

说明:

整数除法只保留整数部分。
给定逆波兰表达式总是有效的。换句话说,表达式总会得出有效数值且不存在除数为 0 的情况。
示例 1:

输入: [“2”, “1”, “+”, “3”, “*”]
输出: 9
解释: ((2 + 1) * 3) = 9
示例 2:

输入: [“4”, “13”, “5”, “/”, “+”]
输出: 6
解释: (4 + (13 / 5)) = 6
示例 3:

输入: [“10”, “6”, “9”, “3”, “+”, “-11”, “", “/”, "”, “17”, “+”, “5”, “+”]
输出: 22
解释:
((10 * (6 / ((9 + 3) * -11))) + 17) + 5
= ((10 * (6 / (12 * -11))) + 17) + 5
= ((10 * (6 / -132)) + 17) + 5
= ((10 * 0) + 17) + 5
= (0 + 17) + 5
= 17 + 5
= 22

逆波兰式,用退栈的方式,很好解决;但有clean code hand book上的扩展,提出,如何提高该题目的扩展性,即继续添加符号,但不用怎么修改代码;所想当到的扩展方法 通过map[op string][f func]的方式实现。并且代码也变得简介许多,见code2.

  • code1
package main

import "fmt"
import "strconv"

type stack struct {
	data []string
}

func (s *stack) push(d string) {
	s.data = append(s.data[:], d)
}
func (s *stack) pop() string {
	if len(s.data) > 0 {
		p := s.data[len(s.data)-1]
		s.data = s.data[:len(s.data)-1]
		return p
	} else {
		panic("null")
	}
}
func(s*stack)show(){
	fmt.Println(s.data)
}
func (s *stack) size() int {
	return len(s.data)
}
func evalRPN(tokens []string) int {
	var sk stack
	for i := 0; i < len(tokens); i++ {
		if tokens[i] == "+" {
			if sk.size() >= 2 {
				a,_ := strconv.Atoi(sk.pop())
				b,_ := strconv.Atoi(sk.pop())

				c:=a+b
				sk.push(strconv.Itoa(c))
			}
		} else if tokens[i] == "/" {
			if sk.size() >= 2 {
				a,_ := strconv.Atoi(sk.pop())
				b,_ := strconv.Atoi(sk.pop())
				c:=b/a
				sk.push(strconv.Itoa(c))
			}

		} else if tokens[i] == "*" {
			if sk.size() >= 2 {
				a,_ := strconv.Atoi(sk.pop())
				b,_ := strconv.Atoi(sk.pop())
				c:=b*a
				sk.push(strconv.Itoa(c))
			}

		} else if tokens[i] == "-" {
			if sk.size() >= 2 {
				a,_ := strconv.Atoi(sk.pop())
				b,_ := strconv.Atoi(sk.pop())
				c:=b-a
				sk.push(strconv.Itoa(c))
			}
		} else {
			sk.push(tokens[i])
		}
	}
	d,_:=strconv.Atoi(sk.pop())
	return d
}
func main() {
	fmt.Println(evalRPN([]string{"2", "1", "+", "3", "*"}))
	fmt.Println(evalRPN([]string{"4", "13", "5", "/", "+"}))
	fmt.Println(evalRPN([]string{"10", "6", "9", "3", "+", "-11", "*", "/", "*", "17", "+", "5", "+"}))
}
  • code2:扩展
package main

import "fmt"
import "strconv"

type stack struct {
	data []string
}

func (s *stack) push(d string) {
	s.data = append(s.data[:], d)
}
func (s *stack) pop() string {
	if len(s.data) > 0 {
		p := s.data[len(s.data)-1]
		s.data = s.data[:len(s.data)-1]
		return p
	} else {
		panic("null")
	}
}
func (s *stack) size() int {
	return len(s.data)
}
func fadd(a,b string)string{
	ai,_ := strconv.Atoi(a)
	bi,_ := strconv.Atoi(b)
	c:=strconv.Itoa(bi+ai)
	return c
}
func fsub(a,b string)string{
	ai,_ := strconv.Atoi(a)
	bi,_ := strconv.Atoi(b)
	c:=strconv.Itoa(bi-ai)
	return c
}
func fmult(a,b string)string{
	ai,_ := strconv.Atoi(a)
	bi,_ := strconv.Atoi(b)
	c:=strconv.Itoa(bi*ai)
	return c
}
func fdiv(a,b string)string{
	ai,_ := strconv.Atoi(a)
	bi,_ := strconv.Atoi(b)
	c:=strconv.Itoa(bi/ai)
	return c
}
var op map[string]func(a,b string)string
func init(){
	op =make(map[string]func(a,b string)string)
	op["+"]=fadd
	op["-"]=fsub
	op["*"]=fmult
	op["/"]=fdiv
}
func evalRPN(tokens []string) int {
	var sk stack
	for i := 0; i < len(tokens); i++ {
		if p,ok:=op[tokens[i]];ok {
			if sk.size() >= 2 {
				sk.push(p(sk.pop(),sk.pop()))
			}
		} else {
			sk.push(tokens[i])
		}
	}
	d,_:=strconv.Atoi(sk.pop())
	return d
}
func main() {
	fmt.Println(evalRPN([]string{"2", "1", "+", "3", "*"}))
	fmt.Println(evalRPN([]string{"4", "13", "5", "/", "+"}))
	fmt.Println(evalRPN([]string{"10", "6", "9", "3", "+", "-11", "*", "/", "*", "17", "+", "5", "+"}))
}

猜你喜欢

转载自blog.csdn.net/scylhy/article/details/87654987
今日推荐