[백준 C] 10757 : 큰 수 A+B

anfruf·2022년 7월 14일

백준 C언어

목록 보기
62/62
  1. C언어 : 기본수학1(8)

15.JUL.2022

문제 : 기본수학1

두 정수 A와 B를 입력받은 다음, A+B를 출력하는 프로그램을 작성하시오.
첫째 줄에 A와 B가 주어진다. (0 < A,B < 1010000)

문제 풀이

#include <stdio.h>
#include <string.h>

void reverse(char arr[]) { // 문자열을 넘겨받아 뒤집어주기
	
    char tmp;
    
    // 뒤집는다==문자열의 반만 서로 순서를 뒤바꾸면 된다. (streln /2)
	for (int i = 0; i < strlen(arr) /2; i++) 
	{
		tmp = arr[i];
		arr[i] = arr[strlen(arr) - i - 1]; // -1=='\0' 빼주기
		arr[strlen(arr) - i - 1] = tmp;
	}
}

int main() {
	// 숫자 a,b를 문자열로 받아 처리
    // a+b를 담을 sum의 범위는 당연히 a+b보다 크게 해준다.
	char a[10001] = { 0 }, b[10001] = { 0 }, sum[10005] = { 0 };
	int len, num, carry = 0;

	scanf("%s %s", a, b); // 두 숫자를 문자열로 입력받기
    
    // reverse() == 문자열 뒤집어주기
	reverse(a);
	reverse(b);
	
    // 길이가 더 긴 문자열로 범위를 잡기
    len = strlen(a) > strlen(b) ? strlen(a) : strlen(b);
    
	for (int i = 0; i < len; i++) {
    	// 문자열의 맨 앞(숫자의 일의 자리)부터 둘을 더하기
        // 문자열 상태이므로 '0'을 빼줘야 자기 본래의 값이 들어간다.
        // carry == 올림수
		num = a[i] - '0' + b[i] - '0' + carry;

		// a,b의 길이가 다른 경우, a[i] 또는 b[i]의 값은 null, 애꿎은 '0'값이 마이너스
        // num이 음수가 되버리므로, 다시 양수로 만들어준다.
		while (num < 0) 
        	num += '0';
            
         // 만약 a+b가 올림 수가 발생한다면, 다음 num에 계산할 수 있도록 1로 바꿔줌
		if (num >= 10) carry = 1;
		else carry = 0;

		// 둘을 더한 값의 일의 자리 수만 결과 배열에 저장
		sum[i] = num % 10 + '0';
	}
    // 둘을 더한 후 마지막 올림수가 있을 때 배열 저장
	if (carry) sum[len] = '1';
    
    // 다시 원래의 순서로
	reverse(sum);
	printf("%s", sum);
}

그래 인정합니다. 처음에 unsigned long long으로 풀고 좋다고 있다가 장렬하게 틀렸다.
구글링 해보고 아 저 얘기가 아니었구나 머쓱타드...나만 그런 거 아니라고 믿고 싶어...한 명쯤은..한 명쯤은.....😧

	// 숫자 a,b를 문자열로 받아 처리
    // a+b를 담을 sum의 범위는 당연히 a+b보다 크게 해준다.
	char a[10001] = { 0 }, b[10001] = { 0 }, sum[10005] = { 0 };
	int len, num, carry = 0;

	scanf("%s %s", a, b); // 두 숫자를 문자열로 입력받기

sum 배열의 범위를 더 크게 해주라는 말을 왜 썼냐하면 내가 바로 범위를 똑같이 설정했다가 틀렸기 때문이다. 아주 당당하구나. 항상 vs로 풀이하고 제출하는데, vs에서는 돌아가길래 아무 생각이 없었다.

	void reverse(char arr[]) { // 문자열을 넘겨받아 뒤집어주기
	
    char tmp;
    
    // 뒤집는다==문자열의 반만 서로 순서를 뒤바꾸면 된다. (streln /2)
	for (int i = 0; i < strlen(arr) /2; i++) 
	{
		tmp = arr[i];
		arr[i] = arr[strlen(arr) - i - 1]; // -1=='\0' 빼주기
		arr[strlen(arr) - i - 1] = tmp;
	}
}

숫자를 문자열로 입력받고 난 후, 뒤집어주는 부분은 함수로 만들었다.

넘겨받은 문자열의 반을 나눠 순서를 바꿔주면 되기 때문에 strlen(arr)/2가 범위가 된다. 굳이 예를 들자면 12345를 52341, 54321로 바꾸는 느낌??
main으로 돌아와 보자.

	for (int i = 0; i < len; i++) {
		num = a[i] - '0' + b[i] - '0' + carry;

		while (num < 0) 
        	num += '0';
            
		if (num >= 10) carry = 1;
		else carry = 0;

		sum[i] = num % 10 + '0';
	}
	if (carry) sum[len] = '1';

a,b 둘 중 길이가 더 긴 문자열로 범위를 잡고, 거꾸로 돌린 이 문자열들을 맨 앞에서부터 더해 본다. 맨 앞이 숫자로 쳤을 때는 일의 자리가 되고, 일의 자리를 더했을 때 발생하는 올림 수는 carry로 저장한다.

a,b의 길이가 다른 경우에는 a, b 둘 중 하나가 null일 것이다. 그런데 -'0'이 하나가 더 들어가 있으니, 아스키 값 48이 한 번 더 빠져 num은 음수가 된다. 이런 상태를 방지하기 위해 num이 음수일 때는 양수로 만들어 준다.

둘 사이를 더해 올림수가 발생하면 이 수는 carry에 저장해 다시 for문을 돌 때 다음 num에 더해 올림수 역할을 해준다.
sum 배열에는 둘을 더한 값인 num의 일의 자리 숫자를 넣어준다.(%10)

for문을 나와 carry가 1일 때, 즉 마지막 올림 수도 고이 저장해주자.

이 모든 과정을 거치면 sum 배열을 다시 거꾸로 돌려 원래의 숫자로 만들고 출력하면 된다.

0개의 댓글