// EvaluateExpression evaluates a arithmetic expression and returns the result value. func EvaluateExpression(e string) (int, error) { e += "#" // used as terminated symbol operator := list.NewStack(false, false, true) operator.Push("#") operand := list.NewStack(false, false, true) for !operator.Empty() { c := "" if len(e) != 0 { c = string(e[0]) } if c != "+" && c != "-" && c != "*" && c != "/" && c != "(" && c != ")" && c != "#" && c != "" { operand.Push(c) } else { opt, _ := operator.Top() switch operandPrecede(opt.(string), c) { case 1: operator.Pop() b, _ := operand.Top() operand.Pop() a, _ := operand.Top() operand.Pop() r, err := operate(a.(string), opt.(string), b.(string)) if err != nil { return 0, err } operand.Push(r) continue case 0: operator.Pop() case -1: operator.Push(c) } } if len(e) >= 2 { e = e[1:len(e)] } } r, err := operand.Top() if err != nil { return 0, err } r, err = strconv.Atoi(r.(string)) if err != nil { return 0, err } return r.(int), err }
// MatchQuotationMark checks whether input quotation marks is pair-matched. func MatchQuotationMark(q string) bool { s := list.NewStack(false, false, true) for len(q) != 0 { m := string(q[0]) t, err := s.Top() if err != nil { s.Push(m) } else { if t == "[" && m == "]" { s.Pop() } else if t == "(" && m == ")" { s.Pop() } else if t == "{" && m == "}" { s.Pop() } else { s.Push(m) } } q = q[1:len(q)] } if !s.Empty() { return false } return true }
// NumeralConversion converts i (positive) from one numeral base to another. func NumeralConversion(fromBase, toBase int, i string) (string, error) { s := list.NewStack(false, false, true) pow := 1 iTenBase := 0 for len(i) != 0 { num, err := strconv.Atoi(i[len(i)-1 : len(i)]) if err != nil { return "", err } iTenBase += (num * pow) pow *= fromBase i = i[0 : len(i)-1] } for iTenBase != 0 { s.Push(iTenBase % toBase) iTenBase /= toBase } var buffer bytes.Buffer for !s.Empty() { v, _ := s.Top() buffer.WriteString(strconv.Itoa(v.(int))) s.Pop() } return buffer.String(), nil }