1. 程式人生 > >大數相乘以及其高效演算法

大數相乘以及其高效演算法

測試用例:

999 999

998001

999999999999      999999999999

999999999998000000000001

下面分析下999*999

   6    5   4

   6   5    4

36 30 24

      30 25 20

           24 20 16

-------------------------------

這裡結果 就清楚了

但是要注意    asc 碼  最大是 128    所以要在加的時候就處理好   

下面給出程式碼     普通  最一般的程式碼  

/*
  Name: hondely
  Copyright: hondely
  Author: hondely
  Date: 05/11/11 14:34
  Description: 
*/

#include <iostream>
using namespace std;
void mul(char *ch1, char *ch2)
{
	int len1=strlen(ch1),len2=strlen(ch2);
	char ch3[1000009];
	int i,j,carry;
	for (i=0; i<1000009; i++)
		ch3[i]='\0';//=0
	for (i=0; i<len1; i++)
	{
		for (j=0; j<len2; j++)//下面可能asc碼大於128
		{
			ch3[i+j]=ch3[i+j]+(ch1[i]-'0')*(ch2[j]-'0');//這裡用字元型表示ch3要注意
			if (ch3[i+j]>9&&(i+j)>0)
			{
			   ch3[i+j-1]+=ch3[i+j]/10;
			   ch3[i+j]=ch3[i+j]%10;
			}
		}
	}
	for (i=len1+len2-1; i>0; --i)//防止上面進位時大於9的情況 
	{
		if (ch3[i]>9)
		{
			ch3[i-1]=ch3[i-1]+ch3[i]/10;
			ch3[i]%=10;
		}
	}

	if (ch3[0]>9)//if (ch[3]>99)
	{
		cout<<ch3[0]/10;
		ch3[0]=ch3[0]%10;
	}
	for (i=0; i<len1+len2-1; i++)
		cout<<char(ch3[i]+48);
	cout<<endl;
}
int main()
{
    char ch1[10005],ch2[10005];
    cout<<"please input: ";
    while (cin>>ch1>>ch2)
    {
          mul(ch1,ch2);
    }
    return 0;
}


 下面是傅立葉高效演算法,自己不懂順便貼上過來了   對傅立葉變換一竅不通

#include <iostream>  
#include <cmath>  
#include <complex>  
#include <cstring>  
using namespace std;  
  
const double PI = acos(-1);
typedef complex<double> cp;  
typedef long long int64;  
  
const int N = 1 << 16;  
int64 a[N], b[N], c[N << 1];  
  
void bit_reverse_copy(cp a[], int n, cp b[])  
{  
    int i, j, k, u, m;  
    for (u = 1, m = 0; u < n; u <<= 1, ++m);  
    for (i = 0; i < n; ++i)  
    {  
        j = i; k = 0;  
        for (u = 0; u < m; ++u, j >>= 1)  
            k = (k << 1) | (j & 1);  
        b[k] = a[i];  
    }  
}  
  
void FFT(cp _x[], int n, bool flag)  
{  
    static cp x[N << 1];  
    bit_reverse_copy(_x, n, x);  
    int i, j, k, kk, p, m;  
    for (i = 1, m = 0; i < n; i <<= 1, ++m);  
    double alpha = 2 * PI;  
    if (flag) alpha = -alpha;  
    for (i = 0, k = 2; i < m; ++i, k <<= 1)  
    {  
        cp wn = cp(cos(alpha / k), sin(alpha / k));  
        for (j = 0; j < n; j += k)  
        {  
            cp w = 1, u, t;  
            kk = k >> 1;  
            for (p = 0; p < kk; ++p)  
            {  
                t = w * x[j + p + kk];  
                u = x[j + p];  
                x[j + p] = u + t;  
                x[j + p + kk] = u - t;  
                w *= wn;  
            }  
        }  
    }  
    memcpy(_x, x, sizeof(cp) * n);  
}  
  
void polynomial_multiply(int64 a[], int na, int64 b[], int nb, int64 c[], int &nc)  
{  
    int i, n;  
    i = max(na, nb) << 1;  
    for (n = 1; n < i; n <<= 1);  
    static cp x[N << 1], y[N << 1];  
    for (i = 0; i < na; ++i) x[i] = a[i];  
    for (; i < n; ++i) x[i] = 0;  
    FFT(x, n, 0);  
    for (i = 0; i < nb; ++i) y[i] = b[i];  
    for (; i < n; ++i) y[i] = 0;  
    FFT(y, n, 0);  
    for (i = 0; i < n; ++i) x[i] *= y[i];  
    FFT(x, n, 1);  
    for (i = 0; i < n; ++i)   
    {  
        c[i] =(int64)(x[i].real() / n + 0.5);
    }  
    for (nc = na + nb - 1; nc > 1 && !c[nc - 1]; --nc);  
}  
  
const int LEN = 5, MOD = 100000;  
void convert(char *s, int64 a[], int &n)  
{  
    int len = strlen(s), i, j, k;  
    for (n = 0, i = len - LEN; i >= 0; i -= LEN)  
    {  
        for (j = k = 0; j < LEN; ++j)  
            k = k * 10 + (s[i + j] - '0');  
        a[n++] = k;  
    }  
    i += LEN;  
    if (i)  
    {  
        for (j = k = 0; j < i; ++j)  
            k = k * 10 + (s[j] - '0');  
        a[n++] = k;  
    }  
}  
  
void print(int64 a[], int n)  
{  
    printf("%I64d", a[--n]);  
    while (n) printf("%05I64d", a[--n]);  
    puts("");  
}  
  
char buf[N + 10];  
  
int main()  
{  
    int na, nb, nc;  
      
    while (scanf("%s", buf) != EOF)  
    {  
        bool sign = false;  
        if (buf[0] == '-')  
        {  
            sign = !sign;   
            convert(buf + 1, a, na);  
        }  
        else convert(buf, a, na);  
        scanf("%s", buf);  
        if (buf[0] == '-')  
        {  
            sign = !sign;  
            convert(buf + 1, b, nb);  
        }  
        else convert(buf, b, nb);  
        polynomial_multiply(a, na, b, nb, c, nc);  
        int64 t1, t2;  
        t1 = 0;  
        for (int i = 0; i < nc; ++i)  
        {  
            t2 = t1 + c[i];  
            c[i] = t2 % MOD;  
            t1 = t2 / MOD;  
        }  
        for (; t1; t1 /= MOD) c[nc++] = t1 % MOD;  
        if (sign) putchar('-');  
        print(c, nc);  
    }  
    return 0;  
}