2的幂位数大整数分治算法

#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>

using namespace std;
//500 digits at most
struct Num{
    int num[1000],len;
    Num(){
        memset(num,0,sizeof(num));
        len=1;
    }
    Num(const string &s){
        len=s.size();
        for(int i=0;i<len;++i){
            num[i]=s[len-1-i]-'0';
        }
    }
    Num& operator=(const Num& right){
        copy(right.num,right.num+1000,this->num);
        len=right.len;
        return *this;
    }
    friend ostream& operator<<(ostream &os,const Num &output){
        for(int i=output.len-1;i>=0;--i)
            os<<output.num[i];
        return os;
    }
    friend Num operator+(Num &x,Num &y){
        Num ans;
        ans.len=max(x.len,y.len);
        for(int i=0;i<ans.len;++i){
            ans.num[i]=x.num[i]+y.num[i];
        }
        for(int i=0;i<ans.len;++i){
            ans.num[i+1]+=ans.num[i]/10;
            ans.num[i]%=10;
        }
        if(ans.num[ans.len]) ++ans.len;
        return ans;
    }
    friend Num operator-(const Num &left,const Num& right){
        Num ans;
        ans.len=max(left.len,right.len);
        for(int i=0;i<ans.len;++i)
            ans.num[i]=left.num[i]-right.num[i];
        for(int i=0;i<ans.len;++i){
            if(ans.num[i]<0){
                --ans.num[i+1];
                ans.num[i]+=10;
            }
        }
        while(ans.len>=1 && !ans.num[ans.len-1]) --ans.len;
        return ans;
    }
    friend Num mul(const Num &x,const Num &y){
        if(x.len==1 && y.len==1) return to_string(x.num[0]*y.num[0]);
        Num a,b,c,d,ans;
        int maxlen=max(x.len,y.len),len1=maxlen>>1;
        copy(x.num,x.num+len1,b.num);
        b.len=len1;
        copy(x.num+len1,x.num+maxlen,a.num);
        a.len=maxlen-len1;
        copy(y.num,y.num+len1,d.num);
        d.len=len1;
        copy(y.num+len1,y.num+maxlen,c.num);
        c.len=maxlen-len1;
        Num tem_ac=mul(a,c),tem_bd=mul(b,d),ac,bd,fin_cdab;
        Num cdab=mul(c+d,a+b)-tem_ac-tem_bd;
        copy(tem_ac.num,tem_ac.num+tem_ac.len,ac.num+len1*2);
        ac.len=tem_ac.len+2*len1;
        copy(cdab.num,cdab.num+cdab.len,fin_cdab.num+len1);
        fin_cdab.len=cdab.len+len1;
        ans=ac+fin_cdab;
        ans=ans+tem_bd;
        while(ans.len>1 && !ans.num[ans.len-1]) --ans.len;
        return ans;
    }
    friend Num operator*(const Num &x,const Num &y){
        return mul(x,y);
    }
};

int main()
{
    string a,b;
    while(cin>>a>>b){
        Num x=a,y=b;
        cout<<"***************************************************"<<endl;
        cout<<a<<endl<<"*"<<endl<<b<<endl<<"="<<endl<<x*y<<endl;
        cout<<"***************************************************"<<endl;
    }
    return 0;
}

时间: 2024-10-13 12:18:45

2的幂位数大整数分治算法的相关文章

大整数算法

本文主要整理了几个常用的大整数的算法:大整数加法大整数乘法大整数阶乘大整数幂其实大体的思路都差不多,都是用数组来存储大整数.以下的代码仅仅实现功能,并没有充分详细的参数判断,在实际运用中,肯定是需要考虑的. 大整数相加 1 #include <stdio.h> 2 #include <string.h> 3 #define N 1000 4 void get_num(int *array) 5 { 6 char str[N] = {'\0'}; 7 int loop = 0; 8

JAVA版拆分大整数为2幂的和算法

import java.util.ArrayList; import java.util.List; public class StrTest { public static void main(String[] args) { //模拟生成一个大整数 Long n=ShengCheng(); //拆分这个大整数,看看是由哪些东东组成的 List<Long> list =SplitNumber(n); for(int i=0;i<list.size();i++) { System.out

大整数算法[08] Comba乘法(原理)

★ 引子          原本打算一篇文章讲完,后来发现篇幅会很大,所以拆成两部分,先讲原理,再讲实现.实现的话相对复杂,要用到内联汇编,要考虑不同平台等等. 在大整数计算中,乘法是非常重要的,因为在公钥密码学中模幂运算要频繁使用乘法,所以乘法的性能会直接影响到模幂运算的效率.下面将会介绍两种乘法:基线乘法和 Comba 乘法,尽管他们的原理和计算看起来十分类似,而且算法的时间复杂度都是 O(n^2),但是他们的效率差别是很大的. ★ 基线乘法 (Baseline Multiplication

大整数算法[11] Karatsuba乘法

★ 引子         前面两篇介绍了 Comba 乘法,最后提到当输入的规模很大时,所需的计算时间会急剧增长,因为 Comba 乘法的时间复杂度仍然是 O(n^2).想要打破乘法中 O(n^2) 的限制,需要从一个完全不同的角度来看待乘法.在下面的乘法算法中,需要使用 x 和 y 这两个大整数的多项式基表达式 f(x) 和 g(x) 来表示. 令 f(x) = a * x + b,g(x) = c * x + d,h(x) = f(x) * g(x).这里的 x 相当于一个基,比如十进制下,

【算法设计与分析基础】大整数乘法

#include<iostream> #include<string> #include<time.h> #include<stdlib.h> #include<sstream> using namespace std; class BigDecimal{ private: int max(int a,int b){//获取两数中的最大值 return a^((a^b) & -(a<b)); } public: string n;

大整数算法[01] 大整数的表示和相关定义

★ 相关的数据类型定义 在干正事之前,先定义好各种数据类型还是很有必要的,避免在以后的编码中引起混乱. uintX   X位无符号整形,如uint32表示32位无符号整形 intX    X位有符号整形,如int32表示32位有符号整形 基本数据类型定义: #ifdef _MSC_VER            typedef __int8              int8;            typedef __int16             int16;            typ

[算法]:分治法-求大整数相乘

#问题大整数相乘 #思路说明 对于大整数计算,一般都要用某种方法转化,否则会溢出.但是python无此担忧了. Python支持**"无限精度"的整数,**一般情况下不用考虑整数溢出的问题,而且Python Int类型与任意精度的Long整数类可以无缝转换,超过Int 范围的情况都将转换成Long类型. 例如: >>> 2899887676637907866*1788778992788348277389943 51872581574157002360341697913

大整数算法[08] 有符号加法和减法

★ 引子 前面几篇文章介绍了比较操作,绝对值加法和绝对值减法,现在就可以利用这几个算法构建有符号数的加减算法. ★ 有符号数加法            有符号数的加法分成两种情况:同号和异号. 1.  如果两个数同号,则执行绝对值加法,如果两个数为非负数,则结果为非负数:如果两个数都是负数,则结果也为负数. 2.  如果两个数异号,则要执行绝对值减法,用绝对值较大的数去减绝对值较小的数.最终结果 z 的符号由 x 和 y 的绝对值大小决定:如果 x 的绝对值大于或等于 y,则 z 的符号与 x

大整数算法[02] 基本的操作(维护算法)

上一篇博文简单介绍了大整数的表示方法,这次开始介绍一些基本的算法.       ★ 初始化和清除 编写大整数函数的出发点是bignum结构的初始化和清除,在其他大部分算法当中,这两个算法都会用到. 对于给定的bignum结构,初始化有两种情况:一是仅仅把bignum结构的dp指向NULL,二是初始化的时候顺便分配一定的动态内存,并让dp指针指向这块内存.其实我本来打算只用第二种方式进行初始化,不过考虑到初始内存可能分配过多导致内存浪费,于是决定两种方式一起使用.第一种方式的优点是在后面编程中你不