본문 바로가기
  • 소소한 개발자 이야기
Algorithm Study/SW역량테스트

큰 자릿수 뺄셈 (고급)

by Siwan_Min 2020. 7. 3.
728x90

안녕하세요, 오늘은 부산에 있는 회사의 코딩 테스트에서 출제 된 문제를 리뷰해 볼까합니다. 

앞전에 포스팅한 "큰 자릿수 뺄셈" 문제와 유사한 문제였는데요, 정확히 말하면 "큰 자릿수 뺄셈"의 고급 버전이라고 볼 수 있습니다. STL과 string.h의 사용이 불가하고, 앞전의 문제는 정수형만 계산 했는데, 이번 문제는 실수형 문제를 계산하는 문제입니다. 

문제


두 숫자가 주어질 때 그 들의 뺄셈을 계산하는 프로그램을 작성하시오. 각 수는 1 이상 10의 100승 미만의 범위를 가진다.

 

제한사항


(1) STL과 string.h 헤더는 사용할 수 없다. 

(2) 잘못된 입력이 들어 올 시 "error"를 출력한다.

(3) 소수부분이 모두 0일 경우 소수 부분은 출력하지 않는다.
 

입력


첫 번째 줄과 두 번째 줄에 각각 하나의 자연수가 주어진다.

 

출력


첫 번째 줄에 뺄셈의 결과를 출력한다. 

 

예제 입력


첫 번째 줄에 뺄셈의 결과를 출력한다. 

 

예제 입력

1962831868293922.0002321
98979797979799988989.8928

 

예제 출력

-98977835147931695067.8925679

 

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
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
/*
문제 해결 방안:
1. 템프 배열로 문자를 받는다. 
2. 길이를 측정하고, 길이만큼 first배열과 second 배열에
    뒷공간부터 채운다. 
    ex) first[5], 입력: 123 -->> 00123
3. 소수 부분은 앞에서부터 채운다. 
4. 대소 비교를 한다. 
5. 큰 수에서 작은 수를 뺀다. 
*/
 
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
 
//예외 발생하면 Error 처리
bool exceptionTest(char Test[]) {
    
//    bool ExceptCheck = false;
    if (Test[0== '-' && Test[0=='.') {
        printf("error");
        return true;
    }
}
 
//문자열 길이를 구하는 함수
int strlen(char s[], int decimal[], int& DotLen) {
    int idx = 0;
    bool check = false;
    while (s[idx] != '\0') { //길이 반환
        
        if (s[idx] == '.') {
            check = true;
            break;
        }
        idx++;
    }
    decimal[0= 1//소수 부분은 첫번째 인덱스에 1을 넣어준다. 
    if (check == true) {
        int idx2 = idx + 1
        int cnt = 0;
        
        while (s[idx2] != '\0') {
            decimal[idx2 - idx] = s[idx2] - '0';
            idx2++;
            cnt++;
        }
        if (cnt > DotLen) { //결과 출력을 위해 소수 부분의 길이를 구한다. 
            DotLen = cnt;
        }
    }
    return idx;
}
 
int main() {
 
    //freopen("input.txt", "r", stdin);
    char temp[105= { 0. };
    char first[105= { 0, }, second[105= { 0, };
    int firstDot[105= { 0, }, secondDot[105= { 0, };
    int big[105= { 0, }, small[105= { 0, };
    int bigDot[105= { 0, }, smallDot[105= { 0, };
    int result[105= { 0, }, resultDot[105= { 0, };
    int firstLen, secondLen, resultDotLen = -1;
 
    scanf(" %[^\n]s", temp);
    if(exceptionTest(temp) == truereturn 0;
    firstLen = strlen(temp, firstDot, resultDotLen);
 
 
    for (int i = 0; i < firstLen; i++) {
        if (temp[i] == '.'break;
        first[105 - firstLen  + i] = temp[i] - '0';
    }
    
    scanf(" %[^\n]s", temp);
    if (exceptionTest(temp) == truereturn 0;
    secondLen = strlen(temp, secondDot, resultDotLen);
    for (int i = 0; i < secondLen; i++) {
        if (temp[i] == '.'break;
        second[105 - secondLen + i] = temp[i] - '0';
    }
 
    //대소비교
    int compare = -1;
 
    if (firstLen > secondLen) compare = 0;
    else if (firstLen < secondLen) compare = 1;
    else {
        for (int i = 0; i < 105; i++) {
            if (first[i] > second[i]) {
                compare = 0;
                break;
            }
            else if (first[i] < second[i]) {
                compare = 1;
                break;
            }
        }
        if (compare == -1) {
            for (int i = 0; i < 105; i++) {
                if (firstDot[i] > secondDot[i]) {
                    compare = 0;
                    break;
                }
                else if (firstDot[i] < secondDot[i]) {
                    compare = 1;
                    break;
                }
            }
        }
    }
 
    // 양수일 경우
    if (compare == 0) {
        for (int i = 104; i >= 0; i--) {
            
            if (first[i] >= second[i]) {
                result[i] = first[i] - second[i];
            }
            else {
                first[i - 1]--;
                first[i] += 10;
                
                result[i] = first[i] - second[i];
            }
        }
        for (int i = resultDotLen; i >= 1; i--) { 
            if (firstDot[i] >= secondDot[i]) {
                resultDot[i] = firstDot[i] - secondDot[i];
            }
            else {
                firstDot[i - 1]--;
                firstDot[i] += 10;
 
                resultDot[i] = firstDot[i] - secondDot[i];
            }
        }
    }
    //음수일 경우
    else if (compare == 1) {
        for (int i = 104; i >= 0; i--) {
 
            if (second[i] >= first[i]) {
                result[i] = second[i] - first[i];
            }
            else {
                second[i - 1]--;
                second[i] += 10;
 
                result[i] = second[i] - first[i];
            }
        }
        for (int i = resultDotLen; i >= 1; i--) {
            if (secondDot[i] >= firstDot[i]) {
                resultDot[i] = secondDot[i] - firstDot[i];
            }
            else {
                secondDot[i - 1]--;
                secondDot[i] += 10;
 
                resultDot[i] = secondDot[i] - firstDot[i];
            }
        }
    }
    else {
        printf("0");
        return 0;
    }
    //printf("%d\n", resultDotLen);
 
    //여기까지 왔다는건 두 수가 같지 않다는 뜻
    //음수일 경우 "-" 출력
    if (compare == 1printf("-");
    for (int i = 0; i < 105; i++) {
        //0이 아닌 순간부터 출력한다. 
        if (result[i] != 0) {
            for (int j = i; j < 105; j++) {
                printf("%d", result[j]);
            }
            break;
        }
        //마지막 인덱스까지 왔는데, 그 인덱스가 갖는 값이 0이라면
        // 0 이상 1이하의 값을 같는거기 때문에, 0을 출력해준다. 
        if (i == 104 && result[i] == 0printf("0");
    }
    //소수 부분 입력이 있다면
    if (resultDotLen > 0) {
        bool flag = false;
        for (int i = 1; i <= resultDotLen; i++) {
            //소수 부분이 모두 0이 아닌 숫자가 있을 경우
            if (resultDot[i]) { 
                flag = true;
                break;
            }
        }
        if (flag == true) {
            printf(".");
            for (int i = 1; i <= resultDotLen; i++) {
                printf("%d", resultDot[i]);
            }
        }
    }
    for (int i = 0; i <= 2; i++)
    //    printf("%d", secondDot[i]);
    return 0;
}

처음 풀어보는 사람한테 풀라고하면 굉장히 시간이 오래 걸리는 문제인것 같습니다. 생각보다 예외도 많고, 처리해야

할 부분이 너무 많다고 느껴지네요...개인적으로 예상 했던 문제인데, 연습을 안하고 가서 시험 때 제대로 풀지 못한 아쉬움이 너무 큽니다....온라인 테스트에서 덧셈 구현하는 문제가 나와서 "혹시 뺄셈 나올려나?" 했는데 진짜 나와버렸네요...

미리 연습하고 갔더라면 금방 풀 수 있었을텐데....ㅠㅠㅠㅠㅠㅠㅠㅠㅠ결과는 안봐도 광탈 예상입니다...하반기 재도전! 

 

오늘의 교훈: "이거 나올거 같은데?" 하는 문제는 다 풀어보자! 

 

Re: 더 좋은 코드 있으면 공유 해주세요!!!! 지적 달게 받겠습니다!!

728x90

'Algorithm Study > SW역량테스트' 카테고리의 다른 글

[LeetCode] Container With Most Water  (0) 2021.02.27
퀵 정렬(Quick Sort) 구현하기  (0) 2020.08.17
압축된 문자열 풀기!  (0) 2020.07.02
합병 정렬(merge sort)  (0) 2020.06.28
큰 자릿수 뺄셈  (0) 2020.06.28

댓글