c·c++/c++ 프로그래밍

동적할당을 이용한 무한자리수 덧셈

바로이순간 2012. 9. 14. 14:50

#include <iostream> 

#include <cstdlib> 

using namespace std;

int inputStr(char **str, int *n) { 

   int i, x; 

   char *s, *t; 

   // calloc 함수는 인자로, 갯수, 크기를 준다.

   // 그리고 모두 0으로 초기화를 해준다.

   // size를 바꾸어 주기 위해서 포인터로 받았다.

   // 여기서 *n의 값을 바꾸어 주면 메인의 정수값도 바뀌게 된다.

   s=(char *)calloc(*n, 1); 

   // 문자를 담을 공간의 인덱스

   i=0; 

   // 한 문자씩 받기 위해서 getchar() 함수를 사용하였다.

   while(x=getchar()) { 

        // 읽은 문자가 숫자가 아니라면 입력이 끝난다.

        if(!isdigit(x)) break; 

        // s배열에 읽은 문자를 넣어 준다.

        s[i]=x; 

        // 인덱스를 증가 시켜 준다.

        i=i+1; 

        // 만약 읽어들인 문자의 갯수가 할당한 크기와 같다면

        // 그 크기를 2배로 늘려준다.

        if(i>=*n) { 

             // 크기를 2배로 늘려준다.

             t=(char *)calloc(2*(*n), 1);

             // 지금까지 읽어들인 문자들을 복사해 준다. 

             for(i=0;i<*n;++i) t[i]=s[i]; 

             // *n의 값을 바꾸어 준다. (메인의 정수값도 바뀐다)

             *n=2*(*n); 

             // 먼저 할당한 s를 해제한다.

             free(s); 

             // s의 값을 새로 할당받은 주소로 바꾸어 준다.

             s=t; 

        } 

   } 

   // 문자열을 만들기 위해서 맨 끝에 0을 넣어 준다.

   s[i]=0;  

   // 문자열의 주소값을 넣어준다. 메인의 포인터의 값도 바뀌게 된다.

   *str=s;   

   // 문자열의 길이를 반환한다.

   return i; 

}  

int main() { 

   char *stra;  // 첫번째 문자열을 위한 포인터 

   char *strb;  // 두번째 문자열을 위한 포인터

   int  *stRes; // 결과를 구할 정수배열을 위한 포인터

   int sizeA=10, sizeB=10; // 처음에 출발할 때는 크기를 10으로 출발한다.

   int nA=0, nB=0, nC=0;   // 문자열의 길이를 담을 변수

   int i, j, k, x, y, z, carry; // 정수 변수들


   // 첫번째 수를 읽어들인다.

   printf("enter first number: ");

   // 첫번째 수의 길이를 nA에 대입한다. 

   nA=inputStr(&stra, &sizeA); 

   // 두번째 수를 읽는다.

   printf("enter second number: ");

   // 두번째 수의 길이를 nB에 대입한다. 

   nB=inputStr(&strb, &sizeB); 

   // 두수중 큰 수에 1을 더해서 nC에 준다.

   if(nA>=nB) nC=nA+1; else nC=nB+1;  

   // nC개 만큼의 정수를 위한 메모리를 할당한다.

   stRes=(int *)calloc(nC, sizeof(int));

   // 첫째수의 1의 자리를 위한 인덱스

   i=nA-1;

   // 두번째 수의 1의 자리를 위한 인덱스

   j=nB-1;

   // 결과를 담을 배열의 인덱스

   k=0;  

   // 올림수

   carry=0;

   // 첫번째 수와 두번째 수 모두 더할 수가 있을 경우

   while(i>=0 && j>=0) { 

      // 문자를 정수로 바꾸어 준다.

      x=stra[i]-'0'; 

      // 문자를 정수로 바꾸어 준다.

      y=strb[j]-'0'; 

      // 밑에서 올라온 수와 두수를 더한다.

      z=x+y+carry; 

      // 10의 자리수는 위로 올라간다.

      carry=z/10; 

      // 1의 자리수는 결과에 들어 간다.

      z=z%10; 

      stRes[k]=z;

      // 첫번째 수와 두번째 수의 인덱스는 감소한다. (앞으로 온다) 

      i=i-1;

      j=j-1;

      // 결과 수의 인덱스는 증가한다.

      k=k+1;

   }

   // 만약 첫번째 수가 남아 있다면 

   while(i>=0) { 

      // 각자리를 결과에 옮긴다.

      // 이때도 올림수 때문에 값이 변할 수 있다.

      x=stra[i]-'0'; 

      z=x+carry; 

      carry=z/10; 

      z=z%10; 

      stRes[k]=z;

      i=i-1;

      k=k+1; 

   } 

   // 만약 두번째 수가 남아 있다면

   while(j>=0) { 

      // 각자리를 결과에 옮긴다.

      // 이때도 올림수 때문에 값이 변할 수 있다.

      y=strb[j]; 

      z=y+carry; 

      carry=z/10; 

      z=z%10; 

      stRes[k]=z;

      j=j-1;

      k=k+1; 

   } 

   // 모든 수를 다 더한 후에도 올림수가 있을 수도 있다.

   if(carry) {

      stRes[k]=carry;

      k=k+1;

   } 

   // 출력을 위해서 가장 큰 수가 들어 있는 인덱스를 구한다. 

   k=k-1;

   // 각 자리를 출력해 준다.

   while(k>=0) { 

        z=stRes[k]; 

        cout<<z;

        k=k-1; 

   } 

   return 0; 


'c·c++ > c++ 프로그래밍' 카테고리의 다른 글

조건을 가진 확률분포  (0) 2012.09.16
cin.getline 입력  (0) 2012.09.16
단어 갯수세기  (0) 2012.08.31
삼각형의 외심 구하기  (0) 2012.08.23
getline  (0) 2012.08.16