파싱(구문 분석, Parsing)은 문장을 적절한 구성 성분으로 분해한 다음 그것을 분석하여 문장의 구조를 정하는 것이다. PS에서의 파싱은 이보다 조금 더 제한적인 의미로 사용되는 경우가 많으며 이때의 의미는 주로 '문자열을 기준에 따라 여러 데이터로 구분하여 원하는 형태로 만든 뒤 적절하게 처리하는 것'으로 해석할 수 있다.
PS에서 파싱은 수와 수가 아닌 문자들이 섞여 있을 때 이것들을 분리할 경우, 특정한 기호가 정해져 있고 그것이 문자열에 등장하는지의 여부를 사전에 알 수 없거나 등장하는 위치가 변할 수 있는 경우, 길이가 정해지지 않은 문자열이 화이트 스페이스 이외의 다른 문자로 구분되어 입력되는 경우 등에 사용된다. 그밖에 다른 유형도 존재하며 각각의 유형을 적절하게 처리해야 데이터를 편리하게 이용할 수 있다.
파싱을 위해서는 아스키 코드(American Standard Code for Information Interchange, ASCII)를 알고 있는 것이 좋다. 다음은 아스키 코드표이다.
VAL | CHR | VAL | CHR | VAL | CHR | VAL | CHR | VAL | CHR | VAL | CHR | VAL | CHR | VAL | CHR |
0 | NUL | 16 | DLE | 32 | SPC | 48 | 0 | 64 | @ | 80 | P | 96 | ` | 112 | p |
1 | SOH | 17 | DC1 | 33 | ! | 49 | 1 | 65 | A | 81 | Q | 97 | a | 113 | q |
2 | STX | 18 | DC2 | 34 | " | 50 | 2 | 66 | B | 82 | R | 98 | b | 114 | r |
3 | ETX | 19 | DC3 | 35 | # | 51 | 3 | 67 | C | 83 | S | 99 | c | 115 | s |
4 | EOT | 20 | DC4 | 36 | $ | 52 | 4 | 68 | D | 84 | T | 100 | d | 116 | t |
5 | ENQ | 21 | NAK | 37 | % | 53 | 5 | 69 | E | 85 | U | 101 | e | 117 | u |
6 | ACK | 22 | SYN | 38 | & | 54 | 6 | 70 | F | 86 | V | 102 | f | 118 | v |
7 | BEL | 23 | ETB | 39 | ' | 55 | 7 | 71 | G | 87 | W | 103 | g | 119 | w |
8 | BS | 24 | CAN | 40 | ( | 56 | 8 | 72 | H | 88 | X | 104 | h | 120 | x |
9 | HT | 25 | EM | 41 | ) | 57 | 9 | 73 | I | 89 | Y | 105 | i | 121 | y |
10 | LF | 26 | SUB | 42 | * | 58 | : | 74 | J | 90 | Z | 106 | j | 122 | z |
11 | VT | 27 | ESC | 43 | + | 59 | ; | 75 | K | 91 | [ | 107 | k | 123 | { |
12 | FF | 28 | FS | 44 | , | 60 | < | 76 | L | 92 | \ | 108 | l | 124 | | |
13 | CR | 29 | GS | 45 | - | 61 | = | 77 | M | 93 | ] | 109 | m | 125 | } |
14 | SO | 30 | RS | 46 | . | 62 | > | 78 | N | 94 | ^ | 110 | n | 126 | ~ |
15 | SI | 31 | US | 47 | / | 63 | ? | 79 | O | 95 | _ | 111 | o | 127 | DEL |
일반적인 아스키 코드는 위와 같이 표현된다. 각각의 문자는 고유의 아스키 코드값을 가지며 이 값은 $0$ 이상 $127$ 이하로 제한되어 있다. 위의 표는 각각의 문자를 종류에 따라서 다른 색으로 구분해 놓았는데 이에 대한 설명은 다음과 같다.
- 빨간색 문자는 숫자(Digit)를 의미한다. 해당하는 아스키 코드값은 $48\text{~}57$이다.
- 파란색 문자는 알파벳(Alphabet)을 의미한다. 해당하는 아스키 코드값은 대문자가 $65\text{~}90$, 소문자가 $97\text{~}122$이다.
- 초록색 문자는 숫자와 알파벳 이외의 특수 문자를 의미한다. 해당하는 아스키 코드값은 $33\text{~}47, 58\text{~}64, 91\text{~}96, 123\text{~}126$이다.
- 보라색 문자는 화이트 스페이스(White Space)이다. 이 문자들은 입력되는 데이터를 구분하는 용도로 쓰인다. 해당하는 아스키 코드값은 $9\text{~}13, 32$이다.
- 주황색 문자는 그 밖의 문자들이며, 보라색과 주황색 문자들 중 DEL을 제외한 $32$개 문자를 제어문자라고 한다.
다음은 각각의 아스키 문자에 대한 설명이다.
0(Null, NUL): 전송되는 문자들 사이에 시간 간격을 준다. 문자열의 끝을 표시한다.
1(Start of Heading, SOH): 정보 메시지 헤더의 시작을 표시한다.
2(Start of Text, STX): 정보 메시지 헤더의 끝 및 본문의 시작을 표시한다.
3(End of Text, ETX): 본문의 끝을 표시한다.
4(End of Transmission, EOT): 전송의 종료를 표시한다. 데이터 링크를 초기화한다.
5(Enquiry, ENQ): 데이터 링크의 설정 및 응답을 요구한다.
6(Acknowledge, ACK): 수신한 정보 메시지에 대한 긍정 응답을 나타낸다.
7(Bell, BEL): 경고음을 울린다.
8(Backspace, BS): 프린터 헤드나 커서를 왼쪽으로 한 칸 이동한다.
9(Horizontal Tab, HT): 프린터 헤드나 커서를 수평 방향으로 정해진 위치만큼 전진한다.
10(Line Feed, LF): 프린터 헤드나 커서를 다음 줄의 같은 위치로 이동한다.
11(Vertical Tab, VT): 프린터 헤드나 커서를 수직 방향으로 정해진 위치만큼 전진한다.
12(Form Feed, FF): 프린터 헤드나 커서를 다음 페이지의 같은 위치로 이동한다.
13(Carriage Return, CR): 프린터 헤드나 커서를 줄의 맨 앞으로 이동한다.
14(Shift Out, SO): 도형 문자의 사용 종료를 표시한다.
15(Shift In, SI): 도형 문자의 사용 시작을 표시한다.
16(Data Link Escape, DLE): 뒤따르는 글자들의 의미를 바꾼다.
17(Device Control 1, DC1): 장치를 제어한다.
18(Device Control 2, DC2): 장치를 제어한다.
19(Device Control 3, DC3): 장치를 제어한다.
20(Device Control 4, DC4): 장치를 제어한다.
21(Negative Acknowledge, NAK): 수신한 정보 메시지에 대한 부정 응답을 나타낸다.
22(Synchronous Idle, SYN): 문자를 전송하지 않는 상태에서 동기를 유지한다.
23(End of Transmit Block, ETB): 전송 블럭의 종료를 표시한다.
24(Cancel, CAN): 선행 데이터가 틀린 경우 이를 무시한다.
25(End of Medium, EM): 기록 부분의 종료를 표시한다.
26(Substitute, SUB): 잘못된 문자를 치환한다.
27(Escape, ESC): 제어 기능을 추가한다.
28(File Separator, FS): 파일의 경계를 할당한다.
29(Group Separator, GS): 레코드 그룹의 경계를 할당한다.
30(Record Separator, RS): 레코드의 경계를 할당한다.
31(Unit Separator, US): 장치의 경계를 할당한다.
32(Space, SPC): 프린터 헤드나 커서를 오른쪽으로 한 칸 이동한다.
33(Exclamation Mark): 기호 !
34(Double Quotes): 기호 "
35(Number): 기호 #
36(Dollar): 기호 $
37(Procenttecken): 기호 %
38(Ampersand): 기호 &
39(Single Quote): 기호 '
40(Open Parenthesis): 기호 (
41(Close Parenthesis): 기호 )
42(Asterisk): 기호 *
43(Plus): 기호 +
44(Comma): 기호 ,
45(Hyphen): 기호 -
46(Period): 기호 .
47(Slash): 기호 /
48(Zero): 숫자 0
49(One): 숫자 1
50(Two): 숫자 2
51(Three): 숫자 3
52(Four): 숫자 4
53(Five): 숫자 5
54(Six): 숫자 6
55(Seven): 숫자 7
56(Eight): 숫자 8
57(Nine): 숫자 9
58(Colon): 기호 :
59(Semicolon): 기호 ;
60(Less Than): 기호 <
61(Equals): 기호 =
62(Greater Than): 기호 >
63(Question Mark): 기호 ?
64(At Symbol): 기호 @
65(Uppercase A): 대문자 A
66(Uppercase B): 대문자 B
67(Uppercase C): 대문자 C
68(Uppercase D): 대문자 D
69(Uppercase E): 대문자 E
70(Uppercase F): 대문자 F
71(Uppercase G): 대문자 G
72(Uppercase H): 대문자 H
73(Uppercase I): 대문자 I
74(Uppercase J): 대문자 J
75(Uppercase K): 대문자 K
76(Uppercase L): 대문자 L
77(Uppercase M): 대문자 M
78(Uppercase N): 대문자 N
79(Uppercase O): 대문자 O
80(Uppercase P): 대문자 P
81(Uppercase Q): 대문자 Q
82(Uppercase R): 대문자 R
83(Uppercase S): 대문자 S
84(Uppercase T): 대문자 T
85(Uppercase U): 대문자 U
86(Uppercase V): 대문자 V
87(Uppercase W): 대문자 W
88(Uppercase X): 대문자 X
89(Uppercase Y): 대문자 Y
90(Uppercase Z): 대문자 Z
91(Opening Bracket): 기호 [
92(Backslash): 기호 \
93(Closing Bracket): 기호 ]
94(Caret): 기호 ^
95(Underscore): 기호 _
96(Grave Accent): 기호 `
97(Lowercase a): 소문자 a
98(Lowercase b): 소문자 b
99(Lowercase c): 소문자 c
100(Lowercase d): 소문자 d
101(Lowercase e): 소문자 e
102(Lowercase f): 소문자 f
103(Lowercase g): 소문자 g
104(Lowercase h): 소문자 h
105(Lowercase i): 소문자 i
106(Lowercase j): 소문자 j
107(Lowercase k): 소문자 k
108(Lowercase l): 소문자 l
109(Lowercase m): 소문자 m
110(Lowercase n): 소문자 n
111(Lowercase o): 소문자 o
112(Lowercase p): 소문자 p
113(Lowercase q): 소문자 q
114(Lowercase r): 소문자 r
115(Lowercase s): 소문자 s
116(Lowercase t): 소문자 t
117(Lowercase u): 소문자 u
118(Lowercase v): 소문자 v
119(Lowercase w): 소문자 w
120(Lowercase x): 소문자 x
121(Lowercase y): 소문자 y
122(Lowercase z): 소문자 z
123(Opening Brace): 기호 {
124(Vertical Bar): 기호 |
125(Closing Brace): 기호 }
126(Tilde): 기호 ~
127(Delete, DEL): 불필요한 부호를 삭제한다.
PS에서는 주황색 문자들이 사용되는 일이 거의 없어서 나머지 문자들을 잘 처리하는 것이 관건이다. 아래의 연습문제들을 통해서 다양한 종류의 파싱에 익숙해질 수 있다.
[연습문제]
문자, 정수, 문자, 정수를 차례대로 입력받아서 분자량을 구한다. 이 문제는 입력되는 자료형의 순서가 정해져 있어서 간단하게 구현할 수 있다.
문자열을 입력받고 한 문자씩 출력하는데 , 문자만 공백으로 바꿔서 출력한다.
문자열을 입력받고 한 문자씩 출력하는데 , 또는 ; 문자와 공백은 문제에 나온 대로 적절하게 처리한다. 문자열이 공백을 포함하므로 한 줄을 한번에 입력받거나, 문자를 하나씩 입력받아야 한다.
문자 C와 H는 항상 입력되지만 C와 H 사이에 숫자가 하나도 없거나 H 뒤에 숫자가 입력되지 않는 경우가 생길 수 있어서 파싱으로 처리해야 한다. 각각의 계수가 존재하는 경우 계수를 구하고, 존재하지 않는 경우 계수를 $1$로 설정한다.
입력되는 문자열에서 마지막으로 . 문자가 등장하는 위치를 찾고 그 다음에 나오는 부분을 확인해서 확장자를 결정한다.
분자량 구하기 문제의 확장 버전이다. 원리는 1124번과 같은데 처리해야 할 케이스가 조금 많다.
문자열을 입력받고 적절한 위치에 문자 ,를 넣는다.
CodeUp 3027. 연립방정식을 풀어라! (Easy)
파싱으로 각각의 식에서 $x$의 계수와 $y$의 계수, 우변의 값을 구하고 연립방정식을 푼다.
'Algorithm > F. Strings' 카테고리의 다른 글
88. Rabin-Karp (0) | 2021.08.18 |
---|---|
87. Failure Function & Knuth-Morris-Pratt (0) | 2021.08.13 |
86. Regular Expression (0) | 2021.07.28 |
85. Hashing (2) | 2021.07.27 |
83. Strings Intro (0) | 2021.07.23 |