2012年10月12日金曜日

動的割り当てを使用した無限桁の加算




次のプログラムは、動的割り当てを使用して、制限なし整数を入力として
加算するプログラムである。事前に割り当てられたサイズがいっぱいになると、再び2倍の大きさに
配列を割り当てて、コピーして続けて入力を受ける。

入力は1文字ずつキーボードから受け取る作成しました。
入力をファイルに取るように変更することは簡単にできるだろう。

#include <iostream>
#include <cstdio>
#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);
   / / 2番目の数を読む。
   printf( "enter second number:");
   / / 2番目の数の長さを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;
   / / 2番目の数の1の座のためのインデックス
   j = nB-1;
   / /結果を入れる配列のインデックス
   k = 0;
   / /切り上げことができ
   carry = 0;
   / /最初の数と2番目の数も加えることができている場合
   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;
      / /最初の数と2番目の数のインデックスは減少する。 (これから来る)
      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;
}

0 件のコメント:

コメントを投稿