栈_逆波兰表达式_计算器实现_Golang版本

栈_逆波兰表达式_计算器实现_Golang版本,第1张

概述借助栈与逆波兰表达式 实现一个计算器,编程语言用的是Golang。 逆波兰表达式可以讲复杂的计算过程转化为简单的 *** 作过程,进而得出答案。 比如 (a+b)*(b-c) 按照逆波兰表达式的规则得到 :ab+bc-*   然后将该表达式的字符以及符号,按照从左到右的顺序,依次入栈,一碰到符号则将栈顶前两个元素取出,做运算然后放入栈内,重复该 *** 作,直到表达式结束。 下面将结合栈与逆波兰表达式写一个简易计

借助栈与逆波兰表达式 实现一个计算器,编程语言用的是Golang。

逆波兰表达式可以讲复杂的计算过程转化为简单的 *** 作过程,进而得出答案。 比如 (a+b)*(b-c) 按照逆波兰表达式的规则得到 :ab+bc-*

然后将该表达式的字符以及符号,按照从左到右的顺序,依次入栈,一碰到符号则将栈顶前两个元素取出,做运算然后放入栈内,重复该 *** 作,直到表达式结束。

下面将结合栈与逆波兰表达式写一个简易计算器。

运行命令如下

go run counter.go --Expression=\(3-5\)*4-\(5*8\)/3+78*9

代码示例:

package mainimport (	"fmt"	"strconv"	"flag")type StackNode struct {	Data interface{}	next *StackNode}type linkStack struct {	top *StackNode	Count int}func (this *linkStack) Init() {	this.top = nil	this.Count = 0}func (this *linkStack) Push(data interface{}) {	var node *StackNode = new(StackNode)	node.Data = data	node.next = this.top	this.top = node	this.Count++}func (this *linkStack) Pop() interface{} {	if this.top == nil {		return nil	}	returnData := this.top.Data	this.top = this.top.next	this.Count--	return returnData}//Look up the top element in the stack,but not pop.func (this *linkStack) Looktop() interface{} {	if this.top == nil {		return nil	}	return this.top.Data}var str *string = flag.String("Expression","","")func main() {	flag.Parse()	fmt.Println(*str)	fmt.Println(Count(*str))}func Count(data string) float64 {	//Todo 检查字符串输入	var arr []string = generaterpn(data)	return calculaterpn(arr)}func calculaterpn(datas []string) float64 {	var stack linkStack	stack.Init()	for i := 0; i < len(datas); i++ {		if isNumberString(datas[i]) {			if f,err := strconv.Parsefloat(datas[i],64); err != nil {				panic("operatin process go wrong.")			} else {				stack.Push(f)			}		} else {			p1 := stack.Pop().(float64)			p2 := stack.Pop().(float64)			p3 := normalCalculate(p2,p1,datas[i])			stack.Push(p3)		}	}	res := stack.Pop().(float64)	return res}func normalCalculate(a,b float64,operation string) float64 {	switch operation{	case "*":		return a * b	case "-":		return a - b	case "+":		return a + b	case "/":		return a / b	default:		panic("invalID operator")	}}func generaterpn(exp string) []string {	var stack linkStack	stack.Init()	var spiltedStr []string = convertToStrings(exp)	var datas []string	for i := 0; i < len(spiltedStr); i++ { // 遍历每一个字符		tmp := spiltedStr[i] //当前字符		if !isNumberString(tmp) { //是否是数字			// 四种情况入栈			// 1 左括号直接入栈			// 2 栈内为空直接入栈			// 3 栈顶为左括号,直接入栈			// 4 当前元素不为右括号时,在比较栈顶元素与当前元素,如果当前元素大,直接入栈。			if tmp == "(" ||				stack.Looktop() == nil || stack.Looktop().(string) == "(" ||				( compareOperator(tmp,stack.Looktop().(string)) == 1 && tmp != ")" ) {				stack.Push(tmp)			} else { // ) priority				if tmp == ")" { //当前元素为右括号时,提取 *** 作符,直到碰见左括号					for {						if pop := stack.Pop().(string); pop == "(" {							break						} else {							datas = append(datas,pop)						}					}				} else { //当前元素为 *** 作符时,不断地与栈顶元素比较直到遇到比自己小的(或者栈空了),然后入栈。					for {						pop := stack.Looktop()						if pop != nil && compareOperator(tmp,pop.(string)) != 1 {							datas = append(datas,stack.Pop().(string))						} else {							stack.Push(tmp)							break						}					}				}			}		} else {			datas = append(datas,tmp)		}	}	//将栈内剩余的 *** 作符全部d出。	for {		if pop := stack.Pop(); pop != nil {			datas = append(datas,pop.(string))		} else {			break		}	}	return datas}// if return 1,o1 > o2.// if return 0,o1 = 02// if return -1,o1 < o2func compareOperator(o1,o2 string) int {	// + - * /	var o1Priority int	if o1 == "+" || o1 == "-" {		o1Priority = 1	} else {		o1Priority = 2	}	var o2Priority int	if o2 == "+" || o2 == "-" {		o2Priority = 1	} else {		o2Priority = 2	}	if o1Priority > o2Priority {		return 1	} else if o1Priority == o2Priority {		return 0	} else {		return -1	}}func isNumberString(o1 string) bool {	if o1 == "+" || o1 == "-" || o1 == "*" || o1 == "/" || o1 == "(" || o1 == ")" {		return false	} else {		return true	}}func convertToStrings(s string) []string {	var strs []string	bys := []byte(s)	var tmp string	for i := 0; i < len(bys); i++ {		if !isNumber(bys[i]) {			if tmp != "" {				strs = append(strs,tmp)				tmp = ""			}			strs = append(strs,string(bys[i]))		} else {			tmp = tmp+string(bys[i])		}	}	strs = append(strs,tmp)	return strs}func isNumber(o1 byte) bool {	if o1 == '+' || o1 == '-' || o1 == '*' || o1 == '/' || o1 == '(' || o1 == ')' {		return false	} else {		return true	}}
总结

以上是内存溢出为你收集整理的栈_逆波兰表达式_计算器实现_Golang版本全部内容,希望文章能够帮你解决栈_逆波兰表达式_计算器实现_Golang版本所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1288893.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-09
下一篇 2022-06-09

发表评论

登录后才能评论

评论列表(0条)

保存