首页 > 其他分享 >go-计算器

go-计算器

时间:2024-01-20 13:31:48浏览次数:30  
标签:string expr len result str 计算器 go strlens

为了实践一下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

相关文章

  • Go中的整数到字符串的转换
    在Go语言中,我们经常需要将整数转换为字符串。然而,直接使用string()函数进行转换可能会导致意想不到的结果。这是因为string()函数会将整数解释为Unicode字符的代码点,而不是将其转换为对应的数字字符串。错误的转换方式例如,如果我们尝试将整数65转换为字符串:s := stri......
  • GYM102596L Yosupo's Algorithm【分治,支配对】
    给定平面上\(2n\)个点,每个点有坐标\((x_i,y_i)\),权值\(w_i\)及颜色\(c_i\)。所有点满足:若\(c_i=0\),则\(x_i<0\);若\(c_i=1\),则\(x_i>0\)。\(q\)次查询,每次给定\(L_i,R_i\),你需要选择两个点\(i,j\)满足如下条件:\(c_i=0,c_j=1\)。\(x_i<L,x_j>R\)或\(x_......
  • 【踩了一个坑】为什么 golang struct 中的 slice 无法原子赋值
    作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢!cnblogs博客zhihuGithub公众号:一本正经的瞎扯有这样一个结构体:typeMyStstruct{Field[]byte}我在数组排序中想要交换值:funcSwap(arr[]MySt,i,jint){arr[i],arr[j]=arr[j],arr[i]}我猜......
  • 快速录制UI测试脚本,RunnerGo新上脚本录制器
    想快速配置可视化UI自动化测试脚本?RunnerGo近期上线脚本录制器,根据你的测试操作直接生成UI自动化测试脚本,下面是使用方法Step1:下载录制器点击RunnerGo上方插件按钮下载录制器Step2:录制器使用将插件文件拖入浏览器扩展程序点击打开录制器,在浏览器中进行操作时录制器会将操作录制为......
  • 谷歌云 | 企业如何高效处理服务中断?Google Cloud 全面推出个性化服务状态监测
    当云服务发生故障时,理解原因和影响至关重要,这样您才能制定行动方案并作出有效响应。去年8月,谷歌云推出了个性化服务状态监测,提供有关谷歌云服务中断时快速、透明和可操作的沟通,帮助企业更有效地应对事件昨日,谷歌云宣布,包括计算引擎、云存储、所有云网络产品、BigQuery和GoogleK......
  • 快速录制UI测试脚本,RunnerGo新上脚本录制器
    想快速配置可视化UI自动化测试脚本?RunnerGo近期上线脚本录制器,根据你的测试操作直接生成UI自动化测试脚本,下面是使用方法Step1:下载录制器点击RunnerGo上方插件按钮下载录制器 Step2:录制器使用将插件文件拖入浏览器扩展程序 点击打开录制器,在浏览器中进行操作时录制器......
  • Go - Pad a number with zeros when printing
     funcmain(){counter:=0varstrstringfor_,i:=range[]byte("foobar"){letterBin:=fmt.Sprintf("%08b",i)fmt.Println(letterBin)str=str+letterBincounter=counter+len(lett......
  • 像 Google SRE 一样 OnCall
    在GoogleSRE的著作《Google运维解密》(原作名:SiteReliabilityEngineering:HowGoogleRunsProductionSystems)中,GoogleSRE的关键成员们几乎不惜用了三个章节的篇幅描述了在Google他们是如何OnCall的。GoogleSRE实践中,有一个广为人知的理念:减少琐事,用软件工程的方......
  • 《模拟龙生》|500行Go代码写一个随机冒险游戏|巨龙修为挑战开启
    一、前言新年就要到了,祝大家新的一年:......
  • 实操开源版全栈测试工具RunnerGo安装(三)MacOS安装
    以Sonoma14.1.2系统为例视频教程:https://www.bilibili.com/video/BV1fG411e7h2/?spm_id_from=333.999.0.01、下载并安装docker​下载地址:https://docker.p2hp.com/下载后安装2、打开终端,准备docker和docker-compose环境​gitclonehttps://github.com/Runner-Go-T......