问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

大数相乘 快速算法

发布网友 发布时间:2022-05-01 22:58

我来回答

4个回答

热心网友 时间:2022-06-24 16:03

大数乘的最快算法是快速傅立叶变换法,这有一个,但不是我本人写的。
#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;
}

热心网友 时间:2022-06-24 16:03

给你一个吧
速度还可以
自己读下代码
/**************************************
算法复杂度为:O(longhta*longthb)
longtha为乘数的位数
longhtb为被乘数的位数
***************************************/

#include <stdio.h>
#include <string.h>
#include <conio.h>
#define LEN 1000
void mult(char [],char [],char []);
main()
{
char op1[LEN],op2[LEN],op3[LEN*2-1];
scanf("%s%s",op1,op2);
mult(op1,op2,op3);
printf("%s\n",op3);
getch();
return 0;
}
void reverse(char a[])
{
int longth=strlen(a);
int i;
for(i=0;i<longth/2;i++){
char t;
t=a[i];
a[i]=a[longth-i-1];
a[longth-i-1]=t;
}
}
void mult(char op1[LEN],char op2[LEN],char ans[LEN*2-1])
{
char top1[LEN];
char top2[LEN];
strcpy(top1,op1);
strcpy(top2,op2);
reverse(top1);
reverse(top2);
int k;
int top1s=strlen(top1);
int top2s=strlen(top2);
for(k=0;k<top1s+top2s;k++){
ans[k]='0';
}
int i,j;
int jw,ys;
int longth;
for(j=0;j<top2s;j++){
jw=0;
for(i=0;i<top1s;i++){
ys=((top1[i]-'0')*(top2[j]-'0')+jw+ans[i+j]-'0')%10;
jw=((top1[i]-'0')*(top2[j]-'0')+jw+ans[i+j]-'0')/10;
ans[i+j]=ys+'0';
}
if(jw>0){
ans[i+j]=jw+'0';
}
}
longth=i+j-1;
if(jw>0)
ans[longth++]=jw+'0';
ans[longth]='\0';
reverse(ans);
}

热心网友 时间:2022-06-24 16:04

在长度不很大的情况下,FTT不能体现优势,其实只要减少乘法除法应该可以得到相当好的算法。不过大部情况下这些做法都比较复杂,其实简单的查表可能更好。

做一个0-9的乘法表结果m,每次计算时只要c[i +j] = m[ia[i]][ib[j]];就好。
进位也可以同理,0-99的进位表和余数表就可以解决除法和模的问题,不过这不是关键。

热心网友 时间:2022-06-24 16:04

哪里的oj,怎么没听过
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
...干或者杀人放火伤天害理的事 是不是 说谎对老天爷来也是不应该的事... 海尔BCD-206TD重要参数 海尔冰箱BCD_196TDXZ如何调温 农业银行密码锁定,但父母不在家怎么办? 奥比岛,号被盗,只记得初始密码,密保手机等密报全被改,充值记录也找不到... 拳皇97ol进阶称号获得方法介绍_拳皇97ol进阶称号获得方法是什么 有什么工作是周六日休息节假日的除了厂,列出来,最好初中毕业也能进_百... 广汉市新生代家庭农场怎么样? 想要考心理咨询师证书,合格证书,技能证书,能力证书等又是啥区别? 海盗船K70 RGB MK.2游戏机械键盘这个人体工程学键盘性价比怎么样?_百 ... 北大口腔医院第二门诊部地址 关于C语言两个大数相乘 一、 两个大数相乘问题 以前的人烤火用的火笼是什么样的,用什么做的,有什么好处和坏处? 烤火对膝盖有好处吗 如何实现大数相乘? 烤火烤脚有什么好处 痰湿体质烤火炉好吗 怀孕三个月B超单显示双顶径19mm 坐高61mm 子宫左侧壁胎盘0级羊水35mm是男是女啊 步升电暖桌烤火有什么优点? 对背部烤火有什么好处 您好:我怀孕三个月,请帮我看一下B超单, 怀孕三个月的B超单帮忙看下 请问怀孕三个月的B超单胎儿是不是偏小? 怀孕三个月,怎么看B超单辩男女 这是怀孕三个月的B超单,请懂的人帮我看下正常不?谢谢! 天天烤火对人体有什么影响吗? 烤火背部的好处? 烤火的时候需要放水在旁边吗?对身体会有什么好处 十六为什么要烤火 烤火铁观音的功效与作用 北京大学口腔医院第二门诊部怎么样 如何快捷计算大数乘法? 北京大学口腔医院的各个门诊哪个好?- 问一问 C语言大数乘法求解~ C语言课程设计---大数乘法运算 请问北大口腔医院 和 北大口腔医院第二门诊部 是一个医院么?他们之间有什么关系啊?哪家看牙好一点呢? 求一C语言编程:求两个大数的乘积。 北京中诺第二口腔医院怎么样? c语言大数乘法的原理是什么? 北京大学口腔医院第二门诊部和第三门诊部哪个好些啊? 如何在JAVA中,输入两个很大的数字使他们相乘后,得到正确结果结果? 北京口腔第二门诊部种植一颗牙要多少钱? 求一段用C语言计算两个大数乘法的代码,尽量越短越好 C语言课程设计大数乘法和除法 北京大学口腔医院第二门诊部是莆田系吗 描写连翘的句子 描写连翘花的古诗 写连翘的一段话 哪两个最大数相乘积是184