go 命令行计算器:接受用户输入的算数表达式,并输出结果

go 命令行计算器:接受用户输入的算数表达式,并输出结果

示例

请输入算数表达式:99*(99+6)-77/2-3.5
 99*(99+6)-77/2-3.5 的值为:10353.000000

思路:

使用栈先入后出的特点和计算符的优先级,把获取的字符串转为后缀表达式,并同时使用栈来计算结果

1.定义符号优先级(使用map映射绑定)

2.定义栈

3.中缀表达式转后缀表达式函数

4.计算后缀表达式

5.后缀表达式计算函数

各部分代码

1.定义符号优先级(使用map映射绑定)

var priority = map[rune]int{
	'+': 1,
	'-': 1,
	'*': 2,
	'/': 2,
	'(': 0,
}

2.定义栈结构

// 实现栈结构
type SliceStack struct {
	dataStack []interface{}
}

// 创建一个新的初始栈
func NewSliceStack() *SliceStack {
	return &SliceStack{}
}

// 在栈顶放入数据
func (s *SliceStack) Push(data interface{}) {
	s.dataStack = append(s.dataStack, data)
	//append函数:在原切片的末尾添加元素
}

// 栈最上面的数据出栈
func (s *SliceStack) Pop() interface{} {
	if len(s.dataStack) == 0 {
		return nil
	}
	slice := s.dataStack[len(s.dataStack)-1]
	s.dataStack = s.dataStack[:len(s.dataStack)-1]
	//把栈顶下移一位
	return slice
}

// 查看栈顶第一个元素
func (s *SliceStack) Peek() interface{} {
	if len(s.dataStack) == 0 {
		return nil
	}
	return s.dataStack[len(s.dataStack)-1]
}

// 判断栈是否空
func (s *SliceStack) IsEmpty() bool {
	return len(s.dataStack) == 0
}

3.中缀表达式转后缀表达式函数

// 中缀表达式转缀表达式
func convert(shuru string) []interface{} {
    //定义一个存放处理后的字符的切片
    var inter []interface{}
    //创建一个栈,用于存放运算符
    houzhui := NewSliceStack()

    for i := 0; i < len(shuru); i++ {
       //转换输入的字段为rune类型方便值的判断
       char := rune(shuru[i])
       //字符为空格时,跳过此次循环
       if char == ' ' {
          continue
       }
       //使用unicode函数判断char是否为十进制字符
       if unicode.IsDigit(char) || char == '.' {
          num := ""
          //把连着的数字符号整合在一起
          for i < len(shuru) && (unicode.IsDigit(rune(shuru[i])) || rune(shuru[i]) == '.') {
             num += string(shuru[i])
             i++
          }
          i-- //回退一部,因为外层也有一个 i++
          //将字符转化为浮点型
          value, _ := strconv.ParseFloat(num, 64)
          //将处理过后的数据放入inter切片中存放
          inter = append(inter, value)
          //在符号为"("的情况下直接放入字符栈中
       } else if char == '(' {
          houzhui.Push(char)
       } else if char == ')' {
          //在存放运算符的栈不为空,并且栈顶字符不为"("的情况下
          for !houzhui.IsEmpty() && houzhui.Peek().(rune) != '(' {
             //把运算符栈中的运算符取出放进inter中
             inter = append(inter, houzhui.Pop())
          }
          //取出栈中"("
          houzhui.Pop()
       } else {
          //处理运算符优先级
          //在栈不为空,并且新的运算符优先级比栈顶的小的情况下
          for !houzhui.IsEmpty() && priority[houzhui.Peek().(rune)] >= priority[char] {
             //把运算符放入inter中
             inter = append(inter, houzhui.Pop())
          }
          houzhui.Push(char)
       }
    }
    //把剩余的操作符全部放入inter切片中
    for !houzhui.IsEmpty() {
       inter = append(inter, houzhui.Pop())
    }
    //返回切片
    return inter
}

计算后缀表达式

// 计算后缀表达式
func computeDpostfixExpression(inter []interface{}) float64 {
    //创建一个用存放数值
    stored := NewSliceStack()
    //遍历数值
    for _, value := range inter {
       //判断遍历数值的类型
       switch value.(type) {
       case float64:
          //当类型为float64时,把值压入栈中
          stored.Push(value)
       case rune:
          //当值为rune时判定为计算符,调用计算函数
          calculatingFunction(stored, value.(rune))
       }
    }
    //返回栈低最后一个值作为结果
    return stored.Pop().(float64)
}

计算函数

// 计算函数
func calculatingFunction(stored *SliceStack, operator rune) {
	//取出两个操作数
	num1 := stored.Pop().(float64)
	num2 := stored.Pop().(float64)
	var result float64
	switch operator {
	case '+':
		result = num2 + num1
	case '-':
		result = num2 - num1
	case '*':
		result = num2 * num1
	case '/'://除法注意先后顺续不要错
		result = num2 / num1
	}
	//将结果压回栈
	stored.Push(result)
}

完整代码

package main

import (
    "fmt"
    "strconv"
    "unicode"
)

// 1.定义符号优先级
// 2.定义栈
// 3.中缀转后缀表达式
// 4.计算后缀表达式
// 5.计算函数

// map映射绑定字符优先级
var priority = map[rune]int{
    '+': 1,
    '-': 1,
    '*': 2,
    '/': 2,
    '(': 0,
}

// 实现栈结构
type SliceStack struct {
    dataStack []interface{}
}

// 创建一个新的初始栈
func NewSliceStack() *SliceStack {
    return &SliceStack{}
}

// 在栈顶放入数据
func (s *SliceStack) Push(data interface{}) {
    s.dataStack = append(s.dataStack, data)
    //append函数:在原切片的末尾添加元素
}

// 栈最上面的数据出栈
func (s *SliceStack) Pop() interface{} {
    if len(s.dataStack) == 0 {
       return nil
    }
    slice := s.dataStack[len(s.dataStack)-1]
    s.dataStack = s.dataStack[:len(s.dataStack)-1]
    //把栈顶下移一位
    return slice
}

// 查看栈顶第一个元素
func (s *SliceStack) Peek() interface{} {
    if len(s.dataStack) == 0 {
       return nil
    }
    return s.dataStack[len(s.dataStack)-1]
}

// 判断栈是否空
func (s *SliceStack) IsEmpty() bool {
    return len(s.dataStack) == 0
}

// 中缀表达式转缀表达式
func convert(shuru string) []interface{} {
    //定义一个存放处理后的字符的切片
    var inter []interface{}
    //创建一个栈,用于存放运算符
    houzhui := NewSliceStack()

    for i := 0; i < len(shuru); i++ {
       //转换输入的字段为rune类型方便值的判断
       char := rune(shuru[i])
       //字符为空格时,跳过此次循环
       if char == ' ' {
          continue
       }
       //使用unicode函数判断char是否为十进制字符
       if unicode.IsDigit(char) || char == '.' {
          num := ""
          //把连着的数字符号整合在一起
          for i < len(shuru) && (unicode.IsDigit(rune(shuru[i])) || rune(shuru[i]) == '.') {
             num += string(shuru[i])
             i++
          }
          i-- //回退一部,因为外层也有一个 i++
          //将字符转化为浮点型
          value, _ := strconv.ParseFloat(num, 64)
          //将处理过后的数据放入inter切片中存放
          inter = append(inter, value)
          //在符号为"("的情况下直接放入字符栈中
       } else if char == '(' {
          houzhui.Push(char)
       } else if char == ')' {
          //在存放运算符的栈不为空,并且栈顶字符不为"("的情况下
          for !houzhui.IsEmpty() && houzhui.Peek().(rune) != '(' {
             //把运算符栈中的运算符取出放进inter中
             inter = append(inter, houzhui.Pop())
          }
          //取出栈中"("
          houzhui.Pop()
       } else {
          //处理运算符优先级
          //在栈不为空,并且新的运算符优先级比栈顶的小的情况下
          for !houzhui.IsEmpty() && priority[houzhui.Peek().(rune)] >= priority[char] {
             //把运算符放入inter中
             inter = append(inter, houzhui.Pop())
          }
          houzhui.Push(char)
       }
    }
    //把剩余的操作符全部放入inter切片中
    for !houzhui.IsEmpty() {
       inter = append(inter, houzhui.Pop())
    }
    //返回切片
    return inter
}

// 计算后缀表达式
func computeDpostfixExpression(inter []interface{}) float64 {
    //创建一个用存放数值
    stored := NewSliceStack()
    //遍历数值
    for _, value := range inter {
       //判断遍历数值的类型
       switch value.(type) {
       case float64:
          //当类型为float64时,把值压入栈中
          stored.Push(value)
       case rune:
          //当值为rune时判定为计算符,调用计算函数
          calculatingFunction(stored, value.(rune))
       }
    }
    //返回栈低最后一个值作为结果
    return stored.Pop().(float64)
}

// 计算函数
func calculatingFunction(stored *SliceStack, operator rune) {
    //取出两个操作数
    num1 := stored.Pop().(float64)
    num2 := stored.Pop().(float64)
    var result float64
   switch operator {
	case '+':
		result = num2 + num1
	case '-':
		result = num2 - num1
	case '*':
		result = num2 * num1
	case '/': //除法注意先后顺续不要错
		result = num2 / num1
	}
    //将结果压回栈
    stored.Push(result)
}

func main() {
    var shuru string
    fmt.Print("请输入算数表达式:")
    _, err := fmt.Scanln(&shuru)
    if err != nil {
       fmt.Println("输入错误!", err)
       return
    }
    postfix := convert(shuru)
    result := computeDpostfixExpression(postfix)
    fmt.Printf(" %s 的值为:%f\n", shuru, result)
}
  • 8
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值