본문 바로가기
Problem Solving

[C++] [백준 10757] 큰 수 A+B (pps 4-2)

by tls1107 2021. 7. 17.
728x90
반응형


문제 풀기 전 생각 : 

/*
우선 string 변수에 숫자 두개를 저장한다.
두 숫자가 길이가 다를수 있으니 더 짧은 숫자 앞에 '0'들을 추가해 길이를 맞춰준다.

그리고 두 숫자를 더할때 overflow가 발생할 수 있으니 두 숫자 모두 앞에 '0'을 더한다.
그리고 맨 뒤에서부터 a+b+overflow 를 한다. a는 첫번째 숫자의 i번째 char이다. 
b는 두번째 숫자의 i번째 char이다.

만약 오버플로우가 발생하면 overflow라는 변수에 1을 넣고 a+b+overflow-10+'0'을 tmp변수에 넣는다.
발생하지 않으면 0을 넣고  a+b+overflow+'0'를 tmp변수에 넣는다.

그렇게 모든 작업이 끝난후 tmp변수를 리버스 시킨다.
리버스 후 tmp 변수의 첫번째 char가 '0'이라면 해당 char를 erase 함수를 이용해 삭제한다.

그리고 출력한다.
*/

#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <string>
using namespace std;
char c; 

int main() { 
  string tmp1="",tmp2="",tmp,s1="0",s2="0";
  int overflow = 0,a,b;

  cin >> tmp1 >> tmp2;

  if(tmp1.length() < tmp2.length() ){
    tmp = tmp1;
    tmp1 = tmp2;
    tmp2 = tmp;
  }
  for(int i=0 ; i<tmp1.length()-tmp2.length() ; i++){
    s2 += "0"; 
  }
  s1 += tmp1;
  s2 += tmp2;
  tmp = "";
  
  for(int i=0 ; i<s1.length() ; i++){
    a = s1[s1.length() - 1 - i] - '0';
    b = s2[s2.length() - 1 - i] - '0';
    if( a + b + overflow >= 10){
      tmp += a + b + overflow - 10 + '0';
      overflow = 1;
    }
    else {
      tmp += a + b + overflow + '0';
      overflow = 0; 
    }
  }

  reverse(tmp.begin(),tmp.end());
  if(tmp[0] == '0') tmp.erase(0,1);
  cout << tmp << endl;
  
  return 0; 
}

https://www.acmicpc.net/problem/10757

 

10757번: 큰 수 A+B

두 정수 A와 B를 입력받은 다음, A+B를 출력하는 프로그램을 작성하시오.

www.acmicpc.net


풀 때 어려웠던 점 또는 느낀점 :

 

문제를 읽자마자 이렇게 쉬운게 왜 문제로 나온거지?라는 생각을 했다

자세히 보니 unsigned long long 으로도 감당이 안되는 숫자였다...하...

그래서 머리 굴려가면서 풀다가 잠깐 막혀서 남들은 어떻게 풀었나 친구가 푼걸 보니

파이썬은 그냥 바로 더해도 오버플로우가 일어나지 않는듯 했다...

파이썬이 이래서 좋은건가...  뭐 그래서 그냥 나 혼자 해야겠다 해서 머리를 굴리니 

확실히 문제가 풀리긴 한다.

끝까지 포기하지 않는게 중요한것 같다.


개선방안 :

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

void reverse(char arr[])
{
    int len = strlen(arr);
    for (int i = 0; i <     len / 2; i++) {
    char temp = arr[i];
    arr[i] = arr[len - i - 1];
    arr[len - i - 1] = temp;
    }
}

int main(void) {
    char A[10002] = { 0 }, B[10002] = { 0 }, res[10003] = { 0 };
    int carry = 0, i; //carry는 받아올림
    scanf("%s%s", A, B);
    reverse(A);
    reverse(B);
    //더 긴 숫자의 길이 저장

    int len = strlen(A) > strlen(B) ? strlen(A) : strlen(B);
    
    for (i = 0; i < len; i++) {
    //숫자로 변환해 받아올림과 함께 더한다
    int sum = A[i] - '0' + B[i] - '0' + carry;
    //A[i] 또는 B[i]가 null인 경우 불필요한 뺄셈이 발생하므로
    //0 이상이 될 때까지 문자 0의 아스키 코드 값을 더한다
    while (sum < 0) sum += '0';
        if (sum > 9) carry = 1; //받아올림
        else carry = 0;
        res[i] = sum % 10 + '0'; //받아올림 하고 남은 일의 자리 수의 아스키코드를 저장
    }
    if (carry == 1) res[len] = '1'; //가장 큰 자릿수에서 받아올림이 발생하면 배열의 마지막에 1을 추가
    reverse(res); //덧셈이 완료되었으니 역순으로 정렬해 원하는 값으로 복원
    printf("%s", res);
    return 0;
}

차이점이 있다면 char타입의 배열을 사용해서 풀었냐 아니면 string을 활용했냐

그리고 리버스 함수를 직접 만들었냐 라이브러리를 추가해서 사용했냐

정도 인것 같다. 접근 방법은 비슷한거 같다.

728x90
반응형

댓글