ACM: 大数运算(正整数)

 


自己总结的大数运算(大数运算真是纠结,也吃亏不少):

#include <string.h>

#define MAX 105

加法:

void add(char num1[],char num2[],int sum[])      //传入大数1,2.  输出结果sum.
{
        int len1 = strlen(num1);
        int len2 = strlen(num2);

int str1[MAX];
        int str2[MAX];

memset(str1,0,sizeof(str1));
        memset(str2,0,sizeof(str2));
        memset(sum,0,sizeof(sum));
        int i , j;

j = 0;
        for(i = len1-1; i >= 0; --i)
       {
           str1[j++] = num1[i] - '0';
       }

j = 0;
       for(i = len2-1; i >= 0; --i)
      {
          str2[j++] = num2[i] - '0';
       }

for(i = 0; i < MAX; ++i)
      {
          sum[i] = str1[i] + str2[i];
          if(sum[i] > 10)
         {
              sum[i] -= 10;
              sum[i+1] += 1;
          }
       }
}

 

减法:

void subtraction(char num1[],char num2[],int result[])    //传入大数1,2.  输出结果result
{
        int len1 = strlen(num1);
        int len2 = strlen(num2);

int str1[MAX];
        int str2[MAX];
        memset(str1,0,sizeof(str1));
        memset(str2,0,sizeof(str2));
        memset(result,0,sizeof(result));

int i , j;

j = 0;
        for(i = len1-1; i >= 0; --i)
       {
             str1[j++] = num1[i] - '0';
        }

j = 0;
        for(i = len2-1; i >= 0; --i)
       {
             str2[j++] = num2[i] - '0';
       }

for(i = 0; i < MAX; ++i)
      {
            result[i] = str1[i] - str2[i];
            if(result[i] < 0)
           {
               result[i] += 10;
               result[i+1] -= 1;
            }
        }
}

 

乘法:

void mul(char num1[],char num2[],int result[])      //传入大数1,2.  输出结果result
{
        int len1 = strlen(num1);
        int len2 = strlen(num2);

int str1[MAX];
        int str2[MAX];
        memset(str1,0,sizeof(str1));
        memset(str2,0,sizeof(str2));
        memset(result,0,sizeof(int)*2*MAX);
        int i , j;

j = 0;
        for(i = len1-1; i >= 0; --i)
       {
             str1[j++] = num1[i] - '0';
        }

j = 0;
        for(i = len2-1; i >= 0; --i)
       {
              str2[j++] = num2[i] - '0';
        }

for(i = 0; i < len1; ++i)
       {
              for(j = 0; j < len2; ++j)
             {
                    result[i+j] = str1[i] * str2[j];
              }
        }

for(i = 0; i < MAX*2; ++i)
      {
            if(result[i] >= 10)
          {
               result[i+1] += result[i]/10;
               result[i] %= 10;
           }
        }
}

 

除法:   //除法比较特别. 传入大数num,和较小数n,商result,余数remainder.    (有待改进,因为灵感来自大数求mod)

void division(char num[],int n,int &result,int &remainder)

{
        int i;
        int partition[MAX];
        int divide = 0;
        int len = strlen(num)-1;
        memset(partition,0,sizeof(partition));

while(len >= 0)
        {
             int t = 1;
             for(i = 0; i < 4; ++i)
            {
                  if(len < 0)
                  break;
                  partition[divide] = partition[divide] + t*(num[len]-'0');
                  len--;
                  t = t*10;
            }
            divide++;
        }

result = 0;
        remainder = 0;
        for(i = divide-1; i >= 0; --i)
       {
             remainder = partition[i] + remainder*10000;
             result = remainder;
             result = result/n;
             remainder = remainder%n;
        }
}

 

求mod:

void mod(char num[],int n,int &result)  // 传入大数num,和较小数n,余数result
{
        int i;
        int partition[MAX];
        int divide = 0;
        int len = strlen(num)-1;
        memset(partition,0,sizeof(partition));

while(len >= 0)
       {
            int t = 1;
            for(i = 0; i < 4; ++i)
            {
                  if(len < 0)
                       break;
                  partition[divide] = partition[divide] + t*(num[len]-'0');
                  len--;
                  t = t*10;
             }
             divide++;
      }

result = 0;
      for(i = divide-1; i >= 0; --i)
      {
            result = partition[i] + result*10000;
            result = result%n;
       }
}

 

O(n)时间复杂度求解大数求mod:

int mod(char num[],int m)
{
      int len = strlen(num);
      __int64 ans = 0;
      int i;
      for(i = 0; i < len; ++i)
      {
            ans = (__int64)((ans*10 + (num[i]-'0') ) % m);
       }

return ans;
}

 

O(logn)时间复杂度求解a^n mod m  (m <= 10^9):

__int64 pow_mod(__int64 a,__int64 n,int mod)
{
      if(n == 0)
           return 1;
       __int64 t = pow_mod(a,n/2,mod);
       __int64 ans = (__int64) t * t % mod;
       if(n % 2 == 1)
               ans = ans * a %mod;
       return ans;
}

 

三个求余的公式:

(a+b) mod n = ((a mod n) + (b mod n)) mod n ①

(a-b) mod n = ((a mod n) - (b mod n) + n) mod n ②

ab mod n = (a mod n) (b mod n) mod n ③

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值