Advertisement
Guest User

Untitled

a guest
Feb 25th, 2020
115
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.12 KB | None | 0 0
  1. package Calc
  2.  
  3. import (
  4. "fmt"
  5. "os"
  6. "regexp"
  7. "strconv"
  8. "strings"
  9. )
  10.  
  11. func main() {
  12. expression := os.Args[len(os.Args)-1]
  13. fmt.Printf("%v", calculator(expression))
  14. }
  15. func calculator(expression string) string {
  16. expression = strings.ReplaceAll(expression, "(", " ( ")
  17. expression = strings.ReplaceAll(expression, ")", " ) ")
  18. expression = strings.ReplaceAll(expression, "+", " + ")
  19. expression = strings.ReplaceAll(expression, "-", " - ")
  20. expression = strings.ReplaceAll(expression, "*", " * ")
  21. expression = strings.ReplaceAll(expression, "/", " / ")
  22. expressionSlice := strings.Split(expression, " ")
  23. var pureExprSlice []string
  24. for _, val := range expressionSlice {
  25. if val != "" {
  26. pureExprSlice = append(pureExprSlice, val)
  27. }
  28. }
  29. prior := map[string]int{
  30. "+": 1,
  31. "-": 1,
  32. "*": 2,
  33. "/": 2,
  34. }
  35. stackNumbers, stackOperators := Stack{}, Stack{}
  36. for i := 0; i < len(pureExprSlice); i++ {
  37. currToken := pureExprSlice[i] //текущий токен
  38. validTokSymb := regexp.MustCompile("^[+-/*)(]$") //оператор или скобка
  39. validTokNumb := regexp.MustCompile("^[0-9]*$") //число
  40. if validTokSymb.MatchString(currToken) || validTokNumb.MatchString(currToken) {
  41. switch currToken {
  42. case "(":
  43. stackOperators.Push(currToken)
  44. case ")":
  45. topStackOperand := stackOperators.Top()
  46. if topStackOperand == "(" {
  47. stackOperators.Pop()
  48. } else {
  49. i--
  50. makeOperation(&stackNumbers, &stackOperators)
  51. }
  52. case "-", "+", "*", "/":
  53. if stackOperators.Len() == 0 || stackOperators.Top() == "(" || stackOperators.Top() == ")" ||
  54. prior[currToken] > prior[stackOperators.Top().(string)] {
  55. stackOperators.Push(currToken)
  56. } else {
  57. i--
  58. makeOperation(&stackNumbers, &stackOperators)
  59. }
  60. default:
  61. stackNumbers.Push(currToken)
  62. }
  63. } else {
  64. return "Incorrect data"
  65. }
  66. }
  67. for stackOperators.Len() != 0 {
  68. makeOperation(&stackNumbers, &stackOperators)
  69. }
  70. return stackNumbers.Top().(string)
  71. }
  72. func makeOperation(stackNumbers *Stack, stackOperators *Stack) {
  73. operand1String := stackNumbers.Pop().(string)
  74. operand1, err := strconv.Atoi(operand1String)
  75. if err != nil {
  76. os.Exit(1)
  77. }
  78. operand2String := stackNumbers.Pop().(string)
  79. operand2, err := strconv.Atoi(operand2String)
  80. if err != nil {
  81. os.Exit(1)
  82. }
  83. switch stackOperators.Pop() {
  84. case "+":
  85. stackNumbers.Push(strconv.Itoa(operand1 + operand2))
  86. case "-":
  87. stackNumbers.Push(strconv.Itoa(operand2 - operand1))
  88. case "*":
  89. stackNumbers.Push(strconv.Itoa(operand1 * operand2))
  90. case "/":
  91. stackNumbers.Push(strconv.Itoa(operand1 / operand2))
  92. }
  93. }
  94.  
  95. type Stack struct {
  96. top *Element
  97. size int
  98. }
  99.  
  100. type Element struct {
  101. value interface{}
  102. next *Element
  103. }
  104.  
  105. func (s *Stack) Len() int {
  106. return s.size
  107. }
  108.  
  109. func (s *Stack) Push(value interface{}) {
  110. s.top = &Element{value, s.top}
  111. s.size++
  112. }
  113.  
  114. func (s *Stack) Pop() (value interface{}) {
  115. if s.size > 0 {
  116. value, s.top = s.top.value, s.top.next
  117. s.size--
  118. return
  119. }
  120. return nil
  121. }
  122. func (s *Stack) Top() (value interface{}) {
  123. return s.top.value
  124. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement