Go语言用栈实现算术表达式

将中序表达式转成后序表达式,再通过后序表达式计算出值。

package main

//表达式
//author:Xiong Chuan Liang
//date:2015-2-2

import (
	"fmt"
	"github.com/xcltapestry/xclpkg/algorithm"
	"strconv"
	"errors"
)

func main(){

	// 中序表达式       后序表达式
	// a+b            = ab+
	// (a+b)/c        = ab+c/
	// a+b*(c+d)      = abcd+*+
	// a*b+c*(d-e)/f  = ab*cde-*f/+

	//str := "a*b+c*(d-e)/f"
	//str := "1*2+3*(4-5)/6"

	str := "1*2+3*(5-1)/2"

	exp,err := ExpConvert(str)
	if err != nil {
		fmt.Println("中序表达式转后序表达式失败! ",err)
	}else{
		Exp(exp)
	}

	//v := 1*2+3*(4-5)/6
	v := 1*2+3*(5-1)/2
	fmt.Println("标准结果: ",v)

}

func ExpConvert(str string)(string,error){

	var result string
	stack := algorithm.NewStack()
	for _,s := range str {
		ch := string(s)
		if IsOperator(ch) { //是运算符

			if stack.Empty() || ch == "(" {
				stack.Push(ch)
			}else{
				if ch == ")" { //处理括号
					for{
						if stack.Empty() {
							return "",errors.New("表达式有问题! 没有找到对应的\"(\"号")
						}
						if stack.Top().(string) == "(" {
							break
						}
						result += stack.Top().(string)
						stack.Pop()
					}

					//弹出"("
					stack.Top()
					stack.Pop()
				}else{ //非括号
					 //比较优先级
					 for{
					 	if stack.Empty() {
					 		break
					 	}
					 	m := stack.Top().(string)
					 	if Priority(ch) > Priority(m) {
					 		break
					 	}
					 	result += m
					 	stack.Pop()
					 }
					 stack.Push(ch)
				}
			}

		}else{	//非运算符
			result += ch
		} //end IsOperator()

	} //end for range str

	for {
		if stack.Empty() {
	 		break
	 	}
		result += stack.Top().(string)
		stack.Pop()
	}

	fmt.Println("ExpConvert() str    = ",str )
	fmt.Println("ExpConvert() result = ",result)
	return result,nil
}

func Exp(str string){
	fmt.Println("\nCalc \nExp() :",str )
	stack := algorithm.NewStack()
	for _,s := range str {
		ch := string(s)
		if IsOperator(ch) { //是运算符
			if stack.Empty() {
				break
			}
			b := stack.Top().(string)
			stack.Pop()

			a := stack.Top().(string)
			stack.Pop()			

			ia,ib := convToInt32(a,b)
			sv := fmt.Sprintf("%d",Calc(ch,ia,ib))
			stack.Push( sv )
			fmt.Println("Exp() ",a,"",ch,"",b,"=",sv)
		}else{
			stack.Push(ch)
			fmt.Println("Exp() ch: ",ch)
		} //end IsOperator
	}

	//stack.Print()
	if !stack.Empty() {
		fmt.Println("表达式运算结果: ", stack.Top() )
		stack.Pop()
	}
}

func convToInt32(a,b string)(int32,int32){

	ia, erra := strconv.ParseInt(a, 10, 32)
	if erra != nil {
	 	panic(erra)
	}

	ib, errb := strconv.ParseInt(b, 10, 32)
	if errb != nil {
	 	panic(errb)
	}
	return int32(ia),int32(ib)
}

func IsOperator(op string)(bool){
	switch(op){
	case "(",")","+","-","*","/":
		return true
	default:
		return false
	}
}

func Priority(op string)(int){
	switch(op){
	case "*","/":
		return 3
	case "+","-":
		return 2
	case "(":
		return 1
	default:
		return 0
	}
}

func Calc(op string,a,b int32)(int32){

	switch(op){
	case "*":
		return (a * b)
	case "/":
		return (a / b)
	case "+":
		return (a + b)
	case "-":
		return (a - b)
	default:
		return 0
	}
}

运算结果:

ExpConvert() str    =  1*2+3*(5-1)/2
ExpConvert() result =  12*351-*2/+

Calc
Exp() : 12*351-*2/+
Exp() ch:  1
Exp() ch:  2
Exp()  1  *  2 = 2
Exp() ch:  3
Exp() ch:  5
Exp() ch:  1
Exp()  5  -  1 = 4
Exp()  3  *  4 = 12
Exp() ch:  2
Exp()  12  /  2 = 6
Exp()  2  +  6 = 8
表达式运算结果:  8
标准结果:  8

MAIL: [email protected]

BLOG:http://blog.csdn/net/xcl168

时间: 2024-09-30 22:55:41

Go语言用栈实现算术表达式的相关文章

使用栈完成算术表达式的计算

前言:本篇文章讲解如何利用栈,完成一个简单的算术表达式的计算过程.为了简单起见,首先假设操作数是整数,而运算符为四种类型:+.-.*./ 基本思路:为了完成算术表达式的计算,用到了两个栈,一个用于存放操作数,另一个用于存放操作符. 假设:程序中定义了两个栈:operandStack(用来存放操作数).operatorStack(用于存放操作符). 在处理操作数和操作符之前,首先将它们压入栈中.当要处理一个操作符时,从operatorStack中将它弹出,然后将它应用在来自operandStack

c++用栈实现算术表达式的计算

用栈将算术表达式转换成后缀表达式的形式大家应该不陌生了,但是我在实现计算的时候却发现坑还是不少. 题目描述: 读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值. 输入描述: 测试输入包含若干测试用例,每个测试用例占一行,每行不超过200个字符,整数和运算符之间用一个空格分隔.没有非法表达式.当一行中只有0时输入结束,相应的结果不要输出. 输出描述: 对每个测试用例输出1行,即该表达式的值,精确到小数点后2位. 示例1 输入 1 + 2 4 + 2 * 5 - 7 /

双栈计算算术表达式

1.介绍 算术表达式的计算,是比较常见的问题,但这个问题的背后隐藏着栈的思想. 这里就介绍使用两个栈来计算表达式的方法. 2. 算法 2.1 定义: a) 建立两个栈: 一个是数据栈dataStak,用于存放数据: 一个是符号栈operatorStack,用于存放运算符: b) 建立运算符号之间的优先级表,用于比较两个符号之间的优先级: 优先级定义为三种运算结果:>(表示高于),<(表示低于),=(表示相等): 并且对于"("与")",认为两者的优先级相

运用栈把算术表达式+,-,*,/,%(中缀表达式)转换成后缀表达式并且计算出值

原理: 1.首先判断是数值还是符号,如果是数值放进字符数组以#表示结束, 2.如果是符号,放进栈, 3.每个符号之间要比较优先级,如果栈顶符号优先级低,符号进栈,如果相等(即“(” “)”)出栈,栈顶符号优先级高,栈顶元素出栈进入字符数组,得到后缀表达式 4.计算后缀表达式,判断是数字还是符号.直到遇到符号,将前面的数字计算后放进栈,一直重复,知道“\0” 代码(局限用整数,因为有模运算,若要任何类型的代码,我的blog有) 1 #include <stdio.h> 2 #include &l

安卓利用栈和算术表达式优先级实现进阶版计算器

先po上具体的源代码 简单的xml文件 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="

poj3295解题报告(构造、算术表达式运算)

POJ 3952,题目链接http://poj.org/problem?id=3295 题意: 输入由p.q.r.s.t.K.A.N.C.E共10个字母组成的逻辑表达式, 其中p.q.r.s.t的值为1(true)或0(false),即逻辑变量: K.A.N.C.E为逻辑运算符, K --> and:  x && y A --> or:  x || y N --> not :  !x C --> implies :  (!x)||y E --> equals 

SDUTOJ 2484 算术表达式的转换(栈)

算术表达式的转换 Time Limit: 1000MS Memory limit: 65536K 题目描述 小明在学习了数据结构之后,突然想起了以前没有解决的算术表达式转化成后缀式的问题,今天他想解决一下. 因为有了数据结构的基础小明很快就解出了这个问题,但是他突然想到怎么求出算术表达式的前缀式和中缀式呢?小明很困惑.聪明的你帮他解决吧. 输入 输入一算术表达式,以\'#\'字符作为结束标志.(数据保证无空格,只有一组输入) 输出 输出该表达式转换所得到的前缀式 中缀式 后缀式.分三行输出,顺序

栈的应用—算术表达式求值

例三.算术表达式求值 1.问题描述 当一个算术表达式中含有多个运算符,且运算符的优先级不同的情况下,如何才能处理一个算术表达式????? 2.思路 首先我们要知道表达式分为三类:  ①中缀表达式:a+(b-c/d)*e ②前缀表达式+a*-be ③后缀表达式abcd/-e*+ 由于运算符有优先级,所以在计算机中计算一个中缀的表达式非常困难,特别是带括号的更麻烦,而后缀表达式中既无运算符优先又无括号的约束问题因为在后缀表达式中运算符出现的顺序正是计算的顺序,所以计算一个后缀的表达式更简单.所以,可

数据结构实验之栈二:一般算术表达式转换成后缀式

数据结构实验之栈二:一般算术表达式转换成后缀式 Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描述 对于一个基于二元运算符的算术表达式,转换为对应的后缀式,并输出之. 输入 输入一个算术表达式,以'#'字符作为结束标志. 输出 输出该表达式转换所得到的后缀式. 示例输入 a*b+(c-d/e)*f# 示例输出 ab*cde/-f*+ 提示 来源 示例程序 由一般是求后缀式: 1.设立暂时存放运算符的栈: 2.设表达式的结束符为"#