Example #1
0
// Dijkstra's Two-Stack Algorithm for Expression Evaluation
// $ ./evaluate
//   ( 1 + ( ( 2 + 3 ) * ( 4 * 5 ) ) )
//   101.0
// $ ./evaluate
//   ( ( 1 + sqrt ( 5.0 ) ) / 2.0 )
//   1.618033988749895
func main() {
	ops := stack.NewLinked()
	vals := stack.NewLinked()
	stdin := stdin.NewStdin()

	for !stdin.IsEmpty() {
		s, _ := stdin.ReadString()

		if s == "(" {
			// ignore...
		} else if s == "+" {
			ops.Push(s)
		} else if s == "-" {
			ops.Push(s)
		} else if s == "*" {
			ops.Push(s)
		} else if s == "/" {
			ops.Push(s)
		} else if s == "sqrt" {
			ops.Push(s)
		} else if s == ")" {
			// Pop, evaluate, and push result if token is ")"
			var value float64
			op, _ := ops.Pop()
			v, _ := vals.Pop()

			if op == "+" {
				v1, _ := vals.Pop()
				value = v1.(float64) + v.(float64)
			} else if op == "-" {
				v1, _ := vals.Pop()
				value = v1.(float64) - v.(float64)
			} else if op == "*" {
				v1, _ := vals.Pop()
				value = v1.(float64) * v.(float64)
			} else if op == "/" {
				v1, _ := vals.Pop()
				value = v1.(float64) / v.(float64)
			} else if op == "sqrt" {
				value = math.Sqrt(v.(float64))
			}
			vals.Push(value)
		} else {
			// Token not operator or paren: push value
			value, _ := strconv.ParseFloat(s, 64)
			vals.Push(value)
		}
	}

	result, _ := vals.Pop()
	fmt.Println(result.(float64))
}
Example #2
0
/*************************************************************************
 *  Execution: ./stack < input.txt
 *
 *  % more tobe.txt
 *  to be or not to - be - - that - - - is
 *
 *  % ./stack < tobe.txt
 *  to be not that or be (2 left on stack)
 *
 *************************************************************************/
func main() {
	s := stack.NewLinked()
	stdin := stdin.NewStdin()

	for !stdin.IsEmpty() {
		item, _ := stdin.ReadString()
		if item != "-" {
			s.Push(item)
		} else if !s.IsEmpty() {
			item, _ := s.Pop()
			fmt.Printf("%s ", item)
		}
	}

	fmt.Printf("(%d left on stack)\n", s.Size())
}