大数相乘以及其高效算法

news/2024/7/6 0:59:18 标签: 算法, fft, iostream, c, input, date
cle class="baidu_pl">
cle_content" class="article_content clearfix">
content_views" class="htmledit_views"> 测试用例:

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    所以要在加的时候就处理好   

下面给出代码     普通  最一般的代码  

<code class="language-cpp">/*
  Name: hondely
  Copyright: hondely
  Author: hondely
  Date: 05/11/11 14:34
  Description: 
*/

#include <class="tags" href="/tags/IOSTREAM.html" title=iostream>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;
}
code>


 下面是傅里叶高效class="tags" href="/tags/SuanFa.html" title=算法>算法࿰c;自己不懂顺便粘贴过来了   对傅里叶变换一窍不通

<code class="language-cpp">#include <class="tags" href="/tags/IOSTREAM.html" title=iostream>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;  
}
code>


 

cle>

http://www.niftyadmin.cn/n/1285682.html

相关文章

大数相加、相减、

这里直接贴代码了&#xff0c;代码里面有注释 另外里面还有一个是 乘法的&#xff0c;乘法的再上一博客就有提到了&#xff0c;读者可以 clickhere 里面 由于输入的问题可能 有乱码情况 具体的源代码我放在 点击这里进入下载 #include <iostream>usi…

大数 平方根

先把 一些没有 成熟的代码 以及思路放在这里 手动开根号的基本方法&#xff1a;1、整数开平方步骤&#xff1a; &#xff08;1&#xff09;将被开方数从右向左每隔2位用撇号分开&#xff1b; &#xff08;2&#xff09;从左边第一段求得算数平方根的第一位数字&#xf…

hdu 1020

输入&#xff1a;toioynnkpheleaigshareconhtomesnlewx 输出&#xff1a;theresnoplacelikehomeonasnowynightx t o i o y h p k n n e l e a i r a h s g e c o n h s e m o t n l e w x #include <iostream> using namespace std; #include <string.h> char *re…

近日遇到的低级问题

1&#xff0c;TRACE输出信息跟不上for循环的问题&#xff1b; 2&#xff0c;释放内存空间中delete和delete[]的区别&#xff1b; 3&#xff0c;Domoal问题&#xff0c;check框&#xff08;必须生成函数&#xff09;中打勾后弹出另一个对话框的问题。 4&#xff0c;释放没有开…

再论数组与指针

话说已经好久没有进行理论知识补充了&#xff0c;前几天又看到一个朋友的工资上万了&#xff0c;到百度工作去了&#xff0c;真是无限仰慕啊 不废话了&#xff0c;再说下自己对数组的新认识吧&#xff0c;算是一个以前的一个误解了&#xff0c;今天晚上看c专家与编程&#xff…

在ubuntu上安装和使用valgrind

valgrind三大利器&#xff1a; 内存错误检测器时间剖析器空间剖析器 其中又数“内存错误检测器”最为强大。 下面介绍如何在ubuntu上安装和使用valgrind。 步骤一&#xff1a;确保valgrind已被安装 sudo apt-get install valgrind步骤二&#xff1a;去除所有旧的valgrind日志…

解决水平滑块16K限制

水平滑块&#xff1a; 函数调用&#xff1a; // m_NumPicture存储的是当前*.dat文件中样本总数 if( i < m_NumPicture ) { // 控制滚动条至指定位置 OnHScroll( SB_THUMBTRACK, i, &m_BrowseCtrl );}函数体部分&#xff1a; void CSelectDlg::OnHScr…