为了实践一下go语言,弄一个+-*/和有小括号的计算器,其中小括号的嵌套可以任意多个。 代码如下:
package main
import (
"fmt"
"regexp"
"sort"
"strconv"
"strings"
)
func main() {
str := "6-4*(1+(2*((3+4)*2)+2)-(9-5*4)*2)-(2*3-(2+5+3-2*2))+6"
var result []string
for len(result) >= 0 {
re := regexp.MustCompile(`\([^()]*\)`)
result = re.FindAllString(str, -1)
if len(result) == 0 {
fmt.Println(calP2(str))
return
}
str = calP3(str)
//fmt.Println(str)
}
}
func calP3(str string) string {
//1.找出最深一层的嵌套
re := regexp.MustCompile(`\([^()]*\)`)
result := re.FindAllString(str, -1)
//fmt.Printf("%s\n", result)
newresult := resort(result)
//fmt.Println(newresult)
//2.计算最深一层的嵌套表达式的值,即没有括号的+-*/普通运算
var calP2s []string
for _, i := range newresult {
calP2s = append(calP2s, calP2(i))
}
//fmt.Println(calP2s)
//3.在str中,各个嵌套的表达式newresult对应替换成calP2s
for i := 0; i < len(newresult); i++ {
str = strings.ReplaceAll(str, newresult[i], calP2s[i])
}
return str
}
// 计算没有括号的普通运算
// str := "5+9+4-12*4*9*3+4/2/2-2-1-2+8/4-9/3+5*5*4/4/5*5-9/3*3"
func calP2(str string) string {
//找出*/计算的表达式
reNums := regexp.MustCompile(`\d[*/\d]+`)
Nums := reNums.FindAllString(str, -1)
//对*/表达式重新排序
NewNums := resort(Nums)
var p1Sum []string
for _, i := range NewNums {
//计算*/表达式的值
p1 := calP1(i)
p1Sum = append(p1Sum, p1)
}
//对*/表达式进行替换:12*4*9*3,4/2/2,8/4,5*5*4/4/5*5,9/3*3
for i := 0; i < len(NewNums); i++ {
str = strings.ReplaceAll(str, NewNums[i], p1Sum[i])
}
return calP1(str) //计算+-表达式的值
}
// 计算*/或+-表达式的值
// expr="5*5*4/4/5*5"
// expr="6+8-9+4-2-8"
func calP1(str string) string {
reNums1 := regexp.MustCompile(`\d+`)
reOperation1 := regexp.MustCompile(`[+-/*]`)
Nums1 := reNums1.FindAllString(str, -1)
Operation1 := reOperation1.FindAllString(str, -1)
var sum int
sum, _ = strconv.Atoi(Nums1[0])
for i := 1; i < len(Nums1); i++ {
switch Operation1[i-1] {
case "+":
m, _ := strconv.Atoi(Nums1[i])
sum += m
case "-":
m, _ := strconv.Atoi(Nums1[i])
sum -= m
case "*":
m, _ := strconv.Atoi(Nums1[i])
sum *= m
case "/":
m, _ := strconv.Atoi(Nums1[i])
sum /= m
}
}
sumStr := strconv.Itoa(sum)
return sumStr
}
// 计算*/有多少个
// expr="5*5*4/4/5*5"
func lencal(expr string) int {
re := regexp.MustCompile("[+-/*]")
result := re.FindAllString(expr, -1)
return len(result)
}
// 对普通*/表达式重新排序,防止它的子集先被替换了,例如:"9/3"与"9/3*3"
// expr := []string{"12*4*9*3", "4/2/2", "8/4", "9/3", "5*5*4/4/5*5", "9/3*3"}
func resort(expr []string) []string {
type strStruct struct {
index int
strlen int
}
var strlens []strStruct
for i := 0; i < len(expr); i++ {
strlens = append(strlens, strStruct{i, lencal(expr[i])})
}
//对各个表达式的计算长度进行排序
sort.SliceStable(strlens, func(i, j int) bool {
return strlens[i].strlen < strlens[j].strlen
})
var Nums []string
for i := len(strlens) - 1; i >= 0; i-- {
Nums = append(Nums, expr[strlens[i].index])
}
return Nums
}
标签:string,expr,len,result,str,计算器,go,strlens
From: https://blog.51cto.com/tenglongfly/9345487