1. 程式人生 > >高精度乘法,大數相乘

高精度乘法,大數相乘

//之前寫過盜版(高精度乘法),今天寫一下類似正版的吧。

//本文章分成C++和C語言版,以後決定只用C語言學演算法了,感覺這樣對C語言會有更深的瞭解,用到實際公司程式時再用C++和java

//第一個比較容易理解,輸入字串給整型陣列,再對乘法計算規則有點了解即可,基本是打板子.

//第二個是自己寫的,自己對fgets和strlen的聯合運用有了新的理解。(良心推薦:別用gets,完全是害新手的語句!!!).

//方法一

//#include <stdio.h>
//#include <cstring>
//#include <iostream>
//using namespace std;
//
//int main(void){
////將整數給字串
//char number1[1500], number2[1500];
//cin>>number1>>number2;
//int n = strlen(number1), m = strlen(number2);   //strlen不加上後面的‘\0’
//int a[n], b[m], c[3000], i, j;
//
//memset(c, 0, sizeof(c));
////for(i = 0; i < 3000; i++)
////c[i] = 0;
////字串的每一位傳給整型陣列
//
//for(i = 0, j = n - 1; i < n; i++, j--)
//a[i] = number1[j] - '0';
//for(i = 0, j = m - 1; i < m; i++, j--)
//b[i] = number2[j] - '0';
//
////對a, b陣列運算,並將最終結果儲存到c陣列中
//for(i = 0; i < n; i++){
//for(j = 0; j < m; j++){
//c[i + j] += a[i] * b[j];
//}
//}
////需要進位
//for(i = 0; i < n + m; i++){
//if(c[i] >= 10){
//c[i + 1] += c[i] / 10;
//c[i] %= 10;
//}
//}
////需要從後向前輸出
////找到j
//for(j = 2999; j > 0; j--){
//if(c[j] != 0)
//break;
//}
//
//for(i = j; i >= 0; i--)
//cout<<c[i];
//cout<<endl;
//return 0;
//}

//方法二
//禁止再用C++輸入輸出!!!
#include <string.h>
#include <stdio.h>


int main(){
    int i, j;
    char a[100], b[100];   //不能用int的原因:不能控制輸入的個數,具備侷限性
    int a1[100], b1[100], c1[3000];
    int numa, numb;
//    char s[5];
//    fgets(s, 5, stdin);
//    printf("%d\n", strlen(s));


    printf("高精度乘法:\n");
    printf("請輸入數A:");
    fgets(a, 100, stdin);      //特別提醒:若使用fgets輸入字串,後面會自動加上\0,即若本來strlen(a)是1,現在strlen(a)是2.
    printf("請輸入數B:");
    fgets(b, 100, stdin);


    //初始化c1陣列
    memset(c1, 0, sizeof(c1));


    //儲存a, b中的數字個數,避免每次都需要計算
    numa = strlen(a) - 1; //這裡我們統一考慮數字個數不超出100,由於上述fgets的特性,故需要減去一
    numb = strlen(b) - 1;


//    printf("%d\n", numa);
    //將字元陣列賦值給整型陣列, 乘法不能先高位乘每一個低位,而是先低位乘每一個高位,故需要a[]從低位存入a1中
    //類似54*10,應該按照45,01存入陣列,方便後面的乘法,讀者也可以自行改變,不過後面也要改變,本題是為了符合大眾對乘法的理解
    for(i = 0, j = numa - 1; i < numa; i++, j--)
        a1[i] = a[j] - '0';
    for(i = 0, j = numb - 1; i < numb; i++, j--)
        b1[i] = b[j] - '0';


    //此時考驗到乘法的性質,位位相乘(注: 會有大於10的位,故下面進行處理)
    for(i = 0; i < numa; i++){
        for(j = 0; j < numb; j++){
            c1[i + j] += a1[i] * b1[j];
        }
    }


    for(i = 0; i < numa + numb; i++){
        if(c1[i] >= 10){
            c1[i + 1] += c1[i] / 10;    //高位進低位除10後的數類似:高位加上50的5
            c1[i] %= 10;                //低位退10
        }
    }


    //由於需要從高位到低位輸出,故需要在c1陣列中找出不為0的最高位
    for(i = 2999; c1[i] == 0; i--){
        ;
    }
    //輸出最終結果
    for(j = i; j >= 0; j--){
        printf("%d", c1[j]);
    }


    return 0;
}