判断某个用户的存款是否处于0-10万或20万-50万(前后都为闭区间)之间,从而给用户推送相应的营销活动
本功能采用 波兰表达式 后缀表达式进行处理; 读取方式采用出栈入栈的方式进行解读;即 遇到【数值】时进行入栈,遇到【运算符】时进行出栈做计算处理。
以上描述的波兰表达式示例如下:x表示用户的存款,单位万
["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)
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 删除。