// 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)) }
/************************************************************************* * 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()) }