您的位置:首页 > 其它

ACM: 大数运算(正整数)

2016-05-19 23:15 363 查看
 

自己总结的大数运算(大数运算真是纠结,也吃亏不少):
#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


4000
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: