golang实现一个简易计算器

这段代码是一个简单的中缀表达式转后缀表达式(逆波兰表示法)的计算器,它能够接受用户输入的中缀表达式,转换成后缀表达式,并计算出结果。下面是代码的主要思路和步骤:

  1. 初始化栈和优先级映射

    • stackSymol 和 stackNumber 分别用于存储操作符和数字。
    • Priority 映射定义了不同操作符的优先级。
  2. 字符串到整数的转换

    • Atoi 函数用于将字符串转换为整数。
  3. 中缀转后缀

    • transform 函数接收一个中缀表达式字符串,使用正则表达式提取出数字和操作符。
    • 遍历提取出的元素,根据操作符的优先级和括号的存在,将操作符压入 stackSymol 或弹出到 stackNumber
    • 遇到左括号 ( 时,直接压入 stackSymol
    • 遇到右括号 ) 时,弹出 stackSymol 直到遇到左括号 (,并将弹出的操作符压入 stackNumber
    • 其他情况(数字)直接压入 stackNumber
  4. 计算后缀表达式

    • sum1 函数遍历 stackNumber,将数字压入 slience 栈。
    • 遇到操作符时,从 slience 栈中弹出两个数字,执行相应的操作,并将结果压回 slience 栈。
    • 特别注意除法操作时,需要检查除数是否为零,避免除零错误。
  5. 主函数

    • main 函数负责接收用户输入的中缀表达式,调用 transform 函数进行转换,然后调用 sum1 函数计算结果,并输出。

代码

 
package main

import (
	"fmt"
	"regexp"
	"strconv"
)

var stackSymol []string
var stackNumber []string
var Priority = map[string]int{
	"+": 1,
	"-": 1,
	"*": 2,
	"/": 2,
}

// 定义一个函数,将字符串转化为int
func Atoi(fu string) int {
	i, _ := strconv.Atoi(fu)
	return i

}

// 定义一个函数,将中缀转为后缀
func transform(formual string) {
	//正则表达式将符号数字取出
	re := regexp.MustCompile(`(\d+\.\d+|\d+|\+|-|\*|\/|\(|\))`)
	matches := re.FindAllString(formual, -1)
	for _, m := range matches {
		switch m {
		case "+", "-", "*", "/":
			if len(stackSymol) == 0 || stackSymol[len(stackSymol)-1] == "(" || Priority[m] >= Priority[stackSymol[len(stackSymol)-1]] {
				stackSymol = append(stackSymol, m)
			} else if len(stackSymol) != 0 && stackSymol[len(stackSymol)-1] != "(" && Priority[m] < Priority[stackSymol[len(stackSymol)-1]] {
				stackNumber = append(stackNumber, stackSymol[len(stackSymol)-1])
				stackSymol = stackSymol[:len(stackSymol)-1]
				stackSymol = append(stackSymol, m)
			}

		case "(":
			stackSymol = append(stackSymol, m)
		case ")":
			for stackSymol[len(stackSymol)-1] != "(" {
				stackNumber = append(stackNumber, stackSymol[len(stackSymol)-1])
				stackSymol = stackSymol[:len(stackSymol)-1]

			}
			stackSymol = stackSymol[:len(stackSymol)-1]//去除“(”
		default:
			stackNumber = append(stackNumber, m)
		}
	}
	//将stackSymol中全部转入stackNumber
	for len(stackSymol) > 0 {
		stackNumber = append(stackNumber, stackSymol[len(stackSymol)-1])
		stackSymol = stackSymol[:len(stackSymol)-1]
	}

}
//进行计算,返回最终值
func sum1() int {
	var slience = make([]int, 0)
	for _, v := range stackNumber {
		//判断v是否为数字
		if _, err := strconv.Atoi(v); err == nil {
			slience = append(slience, Atoi(v))

		} else {
			right := slience[len(slience)-1]
			slience = slience[:len(slience)-1]
			left := slience[len(slience)-1]
			slience = slience[:len(slience)-1]
			switch v {
			case "+":
				slience = append(slience, right+left)
			case "-":
				slience = append(slience, right-left)
			case "*":
				slience = append(slience, right*left)
			case "/":
				if right == 0 {
					panic("dont zero")
				}
				slience = append(slience, left/right)
			}
		}

	}
	return slience[0]//返回最终值
}
func main() {
	var formula string
	fmt.Printf("输入一个算式")
	fmt.Scan(&formula)
	transform(formula)
	ra := sum1()
	fmt.Println(ra)

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值