一、大数相加(两个正数)
1、最简单的,两个整形大数相加
练习:HDU1002
代码:
#include
#include
#include
using namespace std;
// 两个整形大数相加
string Add(string &num1, string &num2){
string ans = "";
int l1 = num1.length()-1;
int l2 = num2.length()-1;
int tmp1 = 0, tmp2 = 0;
while(l1 >= 0 && l2 >= 0){
tmp2 = tmp1 + num1[l1] - '0' + num2[l2] - '0';
tmp1 = tmp2 / 10;
ans += char(tmp2 % 10 + '0');
l1--, l2--;
}
while(l1 >= 0){
tmp2 = tmp1 + num1[l1] - '0';
tmp1 = tmp2 / 10;
ans += char(tmp2 % 10 + '0');
l1--;
}
while(l2 >= 0){
tmp2 = tmp1 + num2[l2] - '0';
tmp1 = tmp2 / 10;
ans += char(tmp2 % 10 + '0');
l2--;
}
while(tmp1){
ans += char(tmp1 % 10 + '0');
tmp1 /= 10;
}
reverse(ans.begin(), ans.end());
return ans;
}
int main(){
int t;
string num1, num2;
cin>>t;
for(int i = 1; i <= t; i++){
cin>>num1>>num2;
string ans = Add(num1, num2);
if(i > 1) cout<
2、两个浮点大数相加
练习:HDU1753
思路:将数字分成小数和整数两部分,先算小数部分,再算整数部分。与上面的方法基本相同。
代码:
#include
#include
#include
using namespace std;
int find_ch(string &str, char ch){
for(int i = 0; i < str.length(); i++)
if(str[i] == ch) return i;
return -1;
}
string Add(string &num1, string &num2){
string ans = "";
int p1 = find_ch(num1, '.'), p2 = find_ch(num2, '.');
string num11 = "", num21 = "";
if(p1 != -1) num11 = num1.substr(p1+1, num1.length()-p1-1);
if(p2 != -1) num21 = num2.substr(p2+1, num2.length()-p2-1);
int l11 = num11.length()-1, l21 = num21.length()-1;
while(l11 > l21){
ans += num11[l11--];
}
while(l21 > l11){
ans += num21[l21--];
}
int tmp1 = 0, tmp2 = 0;
while(l11 >= 0){
tmp2 = tmp1 + (num11[l11] - '0') + (num21[l21] - '0');
tmp1 = tmp2 / 10;
ans += char(tmp2 % 10 + '0');
l11--, l21--;
}
ans += '.';
string num12, num22;
if(p1 == -1) num12 = num1;
else num12 = num1.substr(0, p1);
if(p2 == -1) num22 = num2;
else num22 = num2.substr(0, p2);
int l12 = num12.length()-1, l22 = num22.length()-1;
while(l12 >= 0 && l22 >= 0){
tmp2 = tmp1 + (num12[l12] - '0') + (num22[l22] - '0');
tmp1 = tmp2 / 10;
ans += char(tmp2 % 10 + '0');
l12 --, l22 --;
}
while(l12 >= 0){
tmp2 = tmp1 + (num12[l12] - '0');
tmp1 = tmp2 / 10;
ans += char(tmp2 % 10 + '0');
l12 --;
}
while(l22 >= 0){
tmp2 = tmp1 + (num22[l22] - '0');
tmp1 = tmp2 / 10;
ans += char(tmp2 % 10 + '0');
l22 --;
}
while(tmp1){
ans += char(tmp1 % 10 + '0');
tmp1 /= 10;
}
reverse(ans.begin(), ans.end());
int p = ans.length() - 1;
// cout<<"* "<>num1>>num2){
string ans = Add(num1, num2);
cout<
二、大数相减(两个正数)
两个正整数相减
代码:
#include
#include
#include
using namespace std;
string Sub(string &num1, string &num2){
string ans = "";
int l1 = num1.length() - 1;
int l2 = num2.length() - 1;
bool neg = false;
if(l2 > l1 || num1 < num2){
string tmp = num1;
num1 = num2;
num2 = tmp;
neg = true;
swap(l1, l2);
}
int tmp1 = 0, tmp2 = 0;
while(l2 >= 0){
tmp2 = (num1[l1] - num2[l2]) - tmp1;
if(tmp2 < 0){
tmp2 += 10;
tmp1 = 1;
}else{
tmp1 = 0;
}
ans += char(tmp2 + '0');
l1--, l2--;
}
while(l1 >= 0){
tmp2 = (num1[l1] - '0') - tmp1;
if(tmp2 < 0){
tmp2 += 10;
tmp1 = 1;
}else{
tmp1 = 0;
}
ans += char(tmp2 + '0');
l1--;
}
int p = ans.length() - 1;
while(ans[p] == '0' && p > 0) p --;
ans = ans.substr(0, p+1);
if(neg) ans += '-';
reverse(ans.begin(), ans.end());
return ans;
}
int main(){
string num1, num2;
while(cin>>num1>>num2){
string ans = Sub(num1, num2);
cout<
三、大数乘法(两个正数)
两个正整数相乘
练习:HDU1402
超时代码(直接模拟乘法运算,复杂度是O(nm),这个题会超时):
#include
#include
#include
#include
using namespace std;
const int N = 50005;
string Mul(string &num1, string &num2){
int pre_zero = 0; // 处理前导0
while(num1[pre_zero] == '0' && pre_zero < num1.length()-1) pre_zero ++;
num1 = num1.substr(pre_zero, num1.length() - pre_zero);
pre_zero = 0;
while(num2[pre_zero] == '0' && pre_zero < num2.length()-1) pre_zero ++;
num2 = num2.substr(pre_zero, num2.length()-pre_zero);
string zero = "0";
if(num1 == zero || num2 == zero) return zero;
string ans = "";
int l1 = num1.length() - 1;
int l2 = num2.length() - 1;
int tmp1 = 0, tmp2 = 0, start = 0;
while(l1 >= 0){
int p = start ++;
for(int i = l2; i >= 0; i--){
tmp1 = tmp1 + (num1[l1] - '0') * (num2[i] - '0');
if(ans.length() > p){
tmp2 = ans[p] - '0' + tmp1;
ans[p] = char(tmp2 % 10 + '0');
tmp1 = tmp2 / 10;
}else{
ans += char(tmp1 % 10 + '0');
tmp1 /= 10;
}
p ++;
}
while(tmp1){
ans += char(tmp1%10 + '0');
tmp1 /= 10;
}
l1 --;
}
reverse(ans.begin(), ans.end());
return ans;
}
int main(){
char n1[N], n2[N];
while(~scanf("%s%s", n1, n2)){
string num1(n1), num2(n2);
string ans = Mul(num1, num2);
cout<
正解代码(使用FFT傅里叶变换,代码待补充,先给个链接:GO)