前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >逆波兰表达式-应用

逆波兰表达式-应用

原创
作者头像
王宝
发布2024-11-26 19:06:17
发布2024-11-26 19:06:17
890
举报
文章被收录于专栏:核心思路逻辑核心思路逻辑

背景

判断某个用户的存款是否处于0-10万或20万-50万(前后都为闭区间)之间,从而给用户推送相应的营销活动

实现逻辑

本功能采用 波兰表达式 后缀表达式进行处理;  读取方式采用出栈入栈的方式进行解读;即 遇到【数值】时进行入栈,遇到【运算符】时进行出栈做计算处理。

以上描述的波兰表达式示例如下:x表示用户的存款,单位万

代码语言:txt
复制
["0","x","<","0","x","=","+","10","x",">","10","x","=","+","*","20","x","<","20","x","=","+","50","x",">","50","x","=","+","*","+"]

特别注意:表达式中的 "+" 表示或(||)计算;  "*" 表示与(&&)计算

预置值  x=5 ;  堆栈此处以数组进行表示: stack = [] ; 计算时从规则数组前面到后面依次取值计算

计算步骤如下:(其中计算结果中 1表示 true; 0表示false)

1、遍历入栈 0, x     入栈后 stack = ["0", "x"]

2、继续遍历遇到 "<" 进行出栈并将计算后的结果进行入栈。  0 < x  => 1;   入栈后 stack = ["1"]

3、继续遍历入栈 "0","x"    入栈后 stack=["1", "0", "x"]

4、继续遍历遇到 = 进行出栈并将计算后的结果进行入栈。0 = x  => 0;   入栈后 stack = ["1", "0"]

5、继续遍历遇到 + 进行出栈并将计算后的结果进行入栈。1 || 0  => 1;   入栈后 stack = ["1"]

6、继续遍历入栈 "10","x"   入栈后 stack=["1", "10","x"]

7、继续遍历遇到 > 进行出栈并将计算后的结果进行入栈。10 > x  => 1;   入栈后 stack = ["1", "1"]

8、继续遍历入栈 "10","x"  入栈后  stack=["1", "1", "10","x"]

9、继续遍历遇到 = 进行出栈并将计算后的结果进行入栈。10 = x  => 0;   入栈后 stack = ["1", "1", "1"]

10、继续遍历遇到 + 进行出栈并将计算后的结果进行入栈。1 || 1 => 1;   入栈后 stack = ["1", "1"]

11、继续遍历遇到 * 进行出栈并将计算后的结果进行入栈。1 && 1 => 1;   入栈后 stack = ["1"]

12、继续遍历入栈 "20","x"   入栈后 stack=["1", "20", "x"]

13、继续遍历遇到 "<" 进行出栈并将计算后的结果进行入栈。  20 < x  => 0;   入栈后 stack = ["1", "0"]

14、继续遍历入栈 "20","x"  入栈后  stack=["1", "0", "20", "x"]

15、继续遍历遇到 = 进行出栈并将计算后的结果进行入栈。20 = x  => 0;   入栈后 stack = ["1", "0", "0"]

16、继续遍历遇到 + 进行出栈并将计算后的结果进行入栈。0 || 0  => 0;   入栈后 stack = ["1", "0"]

17、继续遍历入栈 "50","x"  入栈后  stack=["1", "0", "50", "x"]

18、继续遍历遇到 > 进行出栈并将计算后的结果进行入栈。50 > x  => 1;   入栈后 stack = ["1", "0", "1"]

19、继续遍历入栈 "50","x"  入栈后  stack=["1", "0",  "1", "50", "x"]

20、继续遍历遇到 = 进行出栈并将计算后的结果进行入栈。50 = x  => 0;   入栈后 stack = ["1", "0", "1", "0"]

21、继续遍历遇到 + 进行出栈并将计算后的结果进行入栈。1 || 0  => 1;   入栈后 stack = ["1", "0", "1"]

22、继续遍历遇到 * 进行出栈并将计算后的结果进行入栈。0 && 1  => 0;   入栈后 stack = ["1", "0"]

23、继续遍历遇到 + 进行出栈并将计算后的结果进行入栈。1 || 0  => 1;   入栈后 stack = ["1"]

24、计算结果为 1 (true)

测试代码

代码语言:txt
复制
package calculate

import (
	"errors"
	"fmt"
	"strconv"
	"testing"
)

var Operate = map[string]bool{"+": true, "-": true, "*": true, "/": true, ">": true, "<": true, "=": true, "&&": true, "||": true}

func TestRCalculate(t *testing.T) {
	x := "15"
	exp := []string{"0", x, "<", "0", x, "=", "+", "10", x, ">", "10", x, "=", "+", "*", "20", x, "<", "20", x, "=", "+", "50", x, ">", "50", x, "=", "+", "*", "+"}
	
	
	a, err := RPNCalculateTest(exp)
	fmt.Println(a)
	fmt.Println(err)
}

func RPNCalculateTest(expArr []string) (int, error) {
	if len(expArr) == 0 {
		return 0, errors.New("Parameter is empty")
	}
	if len(expArr) == 1 {
		num, _ := strconv.Atoi(expArr[0])
		return num, nil
	}
	stack := make([]int, 0, len(expArr))
	for _, v := range expArr {
		if Operate[v] == true { //判断是否是运算符
			if len(stack) < 2 {
				return 0, nil
			}
			b := stack[len(stack)-1]
			stack = stack[:len(stack)-1]
			a := stack[len(stack)-1]
			stack = stack[:len(stack)-1]
			res := -1
			switch v {
			case "+":
				if a+b == 0 {
					res = 0
				} else {
					res = 1
				}
			case "-":
				if a-b == 0 {
					res = 0
				} else {
					res = 1
				}
			case "*":
				if a*b == 0 {
					res = 0
				} else {
					res = 1
				}
			case "/":
				if b == 0 {
					res = 0
				} else {
					if a/b == 0 {
						res = 0
					} else {
						res = 1
					}
				}
			case ">":
				if a > b == false {
					res = 0
				} else {
					res = 1
				}
			case "<":
				if a < b == false {
					res = 0
				} else {
					res = 1
				}
			case "=":
				if a == b == false {
					res = 0
				} else {
					res = 1
				}
			case "&&":
				if a != 0 && b != 0 {
					res = 1
				} else {
					res = 0
				}
			case "||":
				if a == 0 && b == 0 {
					res = 0
				} else {
					res = 1
				}
			}
			if res > -1 {
				stack = append(stack, res)
			}
		} else {
			if num, err := strconv.Atoi(v); err == nil {
				stack = append(stack, num)
			} else {
				return 0, errors.New("expression Error")
			}
		}
	}
	return stack[len(stack)-1], nil
}

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景
  • 实现逻辑
  • 测试代码
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档