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
相关文章推荐
- ACM: 一道累加同余求模 poj1845 (…
- ACM: 一道组合数学的题 poj3252
- ACM: 深搜题
- 总结: 全排列 和 全部子集 (深搜…
- 总结: 从N皇后问题里面的归纳深搜…
- 总结: 广搜 + hash(哈希搜索) (has…
- 总结: 最大连续和 递归分治法 (心…
- 总结: 求逆序对 递归分治(与poj 22…
- 总结: 数塔问题 --> dp 问题 (终…
- 总结: 0-1背包问题 --> 动态规划d…
- 图论: 并查集 + kruskal 求最小…
- 图论: 经典的邻接矩阵 + dijkstra …
- 图论: 优先队列 + dijkstra最短路…
- 图论: 邻接表 + STL优先队列 + dij…
- 图论: Bellman_ford + 队列 + 邻接…
- 图论: bellman_ford 求单源最短路…
- 图论: spfa == Shortest Path Fast…
- 图论: 匈牙利算法 Edmonds
- STL: map类的用法介绍1
- STL-Intelligent IME