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