Stack - 후위 표기법으로 된 식 계산

IT 지식/자료구조|2018. 5. 27. 21:01

1 3 + 4 * 와 같이 후위 표기되어있는 식을 계산하는 프로그램을 stack을 이용해서 만들어라

주의사항
- 피연산자가 너무 많으면 오류를 발생시켜라.
- 피연산자가 적어도 오류를 발생시켜라
- 연산자가 사칙연산 이외의 것이 나오면 예외를 발생시켜라
- 결과는 소수점 둘째까지 반올림해서 표현하라.
- 예외는 이 프로그램을 위한 예외를 새로 만들어라

구성
- 파일을 읽는 메서드가 담긴 util 클래스
- 동작이 진행되는 Main 클래스
- 이 프로그램의 예외 OperatorException 클래스



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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
package practice2;
 
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.Arrays;
import java.util.List;
 
/**
 * 유틸 클래
 * 
 * @author jeongcheol
 *
 */
public class UtilClass {
    
    /**
     * 텍스트 파일을 읽어서 List에 삽입 
     * 
     * @param fileName
     * @param list
     */
    public static void readText(String fileName, List<String> list) {
        try (FileChannel fileChannel = FileChannel.open(Paths.get(fileName), StandardOpenOption.READ)) {
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            
            Charset charset = Charset.defaultCharset();
            int byteCount;
            
            while (true) {
                byteCount = fileChannel.read(buffer);
                
                if (byteCount == -1)
                    break;
                
                buffer.flip();
                String line = charset.decode(buffer).toString().trim();
                
                if (null == line || line.length() == 0) {
                    continue;
                }
                
                list.addAll(Arrays.asList(line.split("\n")));
                buffer.clear();
            }
            fileChannel.close();
        } catch (Exception ex) {
            System.out.println(ex.getMessage());
        }
    }
 
}
 
 
package practice2;
 
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Stack;
 
import org.apache.commons.lang3.StringUtils;
 
public class Main {
 
    private static final List<String> fileList = Arrays.asList("file/practice1/postfix.txt"  , "file/practice1/postfix1.txt");
    private static final List<String> operator = Arrays.asList("+""-""/""*");
    private static final List<String> readText = new ArrayList<>();
    private static final Stack<String> operand = new Stack<>();
 
    public static void main(String args[]) {
        for (String file : fileList) {
            UtilClass.readText(file, readText);
            readText.stream().forEach(x -> {
                try {
                    process(x);
                } catch (OperatorException e) {
                    System.out.println(e.getMessage());
                }
            });
            readText.clear();
        }
    }
 
    /**
     * 서식 처리 
     * 
     * @param str
     * @throws OperatorException
     */
    private static void process(String str) throws OperatorException {
        // 초기
        operand.clear();
 
        // 빈 문자열 체크
        if (StringUtils.isBlank(str)) {
            return;
        }
 
        for (String ch : str.replaceAll("\\r\\n|\\r|\\n|\\n\\r""").split(" ")) {
            if (StringUtils.isNumeric(ch)) {
                operand.push(ch);
            } else if (operator.contains(ch)) {
                checkOperand();
                
                double operand2 = Double.valueOf(operand.pop());
                double operand1 = Double.valueOf(operand.pop());
                
                switch (ch) {
                case "+":
                    operand.push(String.valueOf(operand1 + operand2));
                    break;
 
                case "-":
                    operand.push(String.valueOf(operand1 - operand2));
                    break;
 
                case "*":
                    operand.push(String.valueOf(operand1 * operand2));
                    break;
 
                case "/":
                    operand.push(String.valueOf(operand1 / operand2));
                    break;
                    
                default:
                    throw new OperatorException("An unsupported operator.\n");
                }
            } else {
                throw new OperatorException(ch + " operator is unsupported operator.\n");
            }
        } 
        
        // 결과 확인
        checkResult();
        
        System.out.printf(" = %.2f\n" ,Double.valueOf(operand.peek()));
        System.out.println();
    }
    
    /**
     * 계산 전 피연산자 개수 체크 
     * 
     * @throws OperatorException
     */
    private static void checkOperand() throws OperatorException {
        if (operand.isEmpty() || operand.size() < 2) {
            throw new OperatorException("Not enough operand.\n");
        }
    }
    
    /**
     * 계산 후 피연산자 개수 체크 
     * 
     * @throws OperatorException
     */
    private static void checkResult() throws OperatorException {
        if (operand.size() != 1) {
            throw new OperatorException("Too many operand.\n");
        }
    }
    
 
}
 
 
package practice2;
 
/**
 * 연산 입센션 추가 
 * 
 * @author jeongcheol
 *
 */
public class OperatorException extends Exception {
 
    private static final long serialVersionUID = 1L;
    
    public OperatorException(String errMsg) {
        super(errMsg);
    }
 
}
cs



결과




postfix.txt

postfix1.txt




댓글()