IT 지식/자료구조

Stack을 이용한 문장 완성도 판별 프로그램

위들 wedul 2018. 5. 27. 21:05
반응형

개발을 진행하다보면 기본에 대해 잊어갈때가 있다.

잊지 않기위해 오늘 부터 매주 하나씩 자료구조를 이용한 문제를 풀어봐야겠다.

오늘은 Stack 첫번째 시간으로 문장의 완성도를 확인하는 프로그램을 작성하여 보자.

[제약사항]
- {[(에 대한 괄호들이 정상적으로 닫혀있어야 한다.
- 주석 //, /* 안에 포함된 내용은 무시한다.
- "" double quote에 들어있는 내용을 무시한다.

간단한 프로그램이라 설명은 생략한다.



- Text를 읽고 판별을 진행하는 Main 클래스



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
package practice1;
 
import java.io.IOException;
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.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Stack;
 
public class Main {
    
    public static void main(String[] args) {
        List<String> fileList = Arrays.asList("practice1_file/paren1.txt""practice1_file/paren2.txt""practice1_file/paren3.txt");
        List<String> readText = new ArrayList<>();
        
        for (String file : fileList) {
            readText(file, readText);
            System.out.println(file + " : " + checkSentence(readText));
            readText.clear();
        }
        
    }
    
    /**
     * @param readText
     * @return
     */
    public static boolean checkSentence(List<String> readText) {
        Stack<BracketType> brackets = new Stack<>();
        boolean isMultiComment = false;
        boolean isDoubleQuote = false;
        
        for (String str : readText) {
            int oneLineCommentIndex = str.indexOf("//");
            
            // line 주석 체크
            if (oneLineCommentIndex > 0) {
                str = str.substring(0, oneLineCommentIndex);
            } else if (oneLineCommentIndex == 0) {
                continue;
            }
            
            for (int i = 0; i < str.length(); i++) {
                char c = str.charAt(i);
                
                // 멀티 라인 주석일 경우
                if (isMultiComment) {
                    if ( c == '*' && i + 1 < str.length() && str.charAt(i + 1== '/' ) {
                        isMultiComment = false;
                        i += 1;
                    } else {
                        continue;
                    }
                }
                
                // " 시작인 경우
                if (isDoubleQuote) {
                    if ( c == '"' ) {
                        isDoubleQuote = false;
                        continue;
                    } else {
                        continue;
                    }
                }
                
                // ", /*
                if (c == '"') {
                    isDoubleQuote = true;
                    continue;
                } else if ( c == '/' && i + 1 < str.length() && str.charAt(i + 1== '*' ) {
                    isMultiComment = true;
                    continue;
                }
                 
                // 괄호 체크
                BracketType type = BracketType.getType(c);
                
                if (type != null) {
                    if (!brackets.isEmpty() && brackets.peek().checkBracket(type)) {
                        brackets.pop();
                    } else {
                        brackets.push(type);
                    }
                }
            }
        }
        
        return brackets.isEmpty();
    }
    
    /**
     * 텍스트 읽기
     * 
     * @param fileName
     * @param list
     * @throws IOException
     */
    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.add(line);
                buffer.clear();
            }
            fileChannel.close();
        } catch (Exception ex) {
            System.out.println(ex.getMessage());
        }
    }
    
}
cs





- 괄호에 대한 종류를 담고 있는 Enum 클래스
- 각 괄호를 나타내는 Enum 객체마다 괄호가 정상적으로 닫히는지 여부를 체크하는 메소드가 재정의 되어있음



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
package practice1;
 
/**
 * 문장의 괄호 종류와 체크로직
 * 
 * @author wedul
 *
 */
public enum BracketType implements CheckBracketI {
    BIG_RIGHT_BRACKET('}') {
        @Override
        public boolean checkBracket(BracketType type) {
            return false;
        }
    },
    SMALL_RIGHT_BRACKET(')') {
        @Override
        public boolean checkBracket(BracketType type) {
            return false;
        }
    },
    SMALL_LEFT_BRACKET('(') {
        @Override
        public boolean checkBracket(BracketType type) {
            return type.equals(SMALL_RIGHT_BRACKET);
        }
    },
    BIG_LEFT_BRACKET('{') {
        @Override
        public boolean checkBracket(BracketType type) {
            return type.equals(BIG_RIGHT_BRACKET);
        }
    },
    MIDDLE_LEFT_BRACKET('[') {
        @Override
        public boolean checkBracket(BracketType type) {
            return type.equals(MIDDLE_RIGHT_BRACKET);
        }
    },
    MIDDLE_RIGHT_BRACKET(']') {
        @Override
        public boolean checkBracket(BracketType type) {
            return false;
        }
    };;
    ;
    
    private char data;
    
    private BracketType(char data) {
        this.data = data;
    }
    
    public char getData() {
        return this.data;
    }
    
    /**
     * getType
     * 
     * @param input
     * @return
     */
    public static BracketType getType(char input) {
        for (BracketType type : values()) {
            if (type.getData() == input) {
                return type;
            }
        }
        
        return null;
    }
}
cs




- enum에서 사용된 인터페이스


1
2
3
4
5
6
7
8
9
10
11
12
13
package practice1;
 
/**
 * 괄호의 종류별로 체크하는 메소드를 포함한 인터페이스
 * 
 * @author wedul
 *
 */
public interface CheckBracketI {
    
    boolean checkBracket(BracketType type);
 
}
cs



결과




테스트 파일


paren1.txt

paren2.txt

paren3.txt



728x90
반응형
1 2 3 4