수식 계산 | 스택(Stack) | 수식 표기법 (prefix, infix, postfix)

Algorithm 2019. 8. 28. 18:02
반응형

스택

전위, 중위, 후위 표기법 

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
using System;
using System.Collections.Generic;
using System.Linq;
 
namespace Application
{
    class MainClass
    {
        public static void Main(string[] args)
        {
            Console.WriteLine(2 + 3 * 1);
            string[] tokens = "2 + 3 * 1".Split(' ');
            var result = Calulator.Evalute(tokens);
            Console.WriteLine("result: {0}", result);
        }
    }
 
    public class Calulator {
 
        public static decimal Evalute(string[] infixTokens)
        {
            //중위표기를 후위표기로 변환
            var postfixTokens = ConvertToPostfix(infixTokens);
 
            //후위표기식 계산
            string[] operatiors = { "+""-""*""/"};
            var stack = new Stack<string>();
 
            foreach (var token in postfixTokens) {
                if (operatiors.Contains(token))
                {
                    var n2 = decimal.Parse(stack.Pop());
                    var n1 = decimal.Parse(stack.Pop());
                    var res = Calc(token, n1, n2);
                    stack.Push(res.ToString());
                }
                else {
                    stack.Push(token);
                }
            }
 
            //스택에서 마지막 결과 Pop
            string result = stack.Pop();
            return decimal.Parse(result);
        }
 
        private static string[] ConvertToPostfix(string[] infix) {
            var postfix = new List<string>();
            var stack = new Stack<string>();
 
            foreach (var token in infix) {
                if (token == "+" || token == "-")
                {
                    while (stack.Count > 0)
                    {
                        postfix.Add(stack.Pop());
                    }
                    stack.Push(token);
                }
                else if (token == "*" || token == "/")
                {
                    while (stack.Count > 0 && (stack.Peek() == "*" || stack.Peek() == "/"))
                    {
                        postfix.Add(stack.Pop());
                    }
                    stack.Push(token);
                }
                else {
                    postfix.Add(token);
                }
            }
            //스택에 남은 연산자를 모두 추가
            while (stack.Count > 0) {
                postfix.Add(stack.Pop());
            }
 
            return postfix.ToArray();
        }
 
 
        private static decimal Calc(string op, decimal n1, decimal n2) {
            decimal result = 0;
 
            switch (op)
            {
                case "+":
                    result = n1 + n2;
                    break;
                case "-":
                    result = n1 - n2;
                    break;
                case "*":
                    result = n1 * n2;
                    break;
                case "/":
                    result = n1 / n2;
                    break;
                default:
                    throw new InvalidOperationException();
            }
 
            return result;
        }
    }
}
 
 
 
반응형
: