用string实现大整数加法
2016-04-26 22:33
441 查看
最近在刷欧拉计划的题目,做到其中Problem 25:1000-digit
Fibonacci number时,完全蒙了,不知道从何下手,因为普通的思路计算前50个Fibonacci数就比较费时,还没到12位呢!更别说计算含1000位数字的时候是第多少个Fibonacci数了。因此想到这类题肯定有更巧妙的解法,在网上查询了相关资料,发现可以用来string实现大整数的加法。
大数相加不能直接使用基本的int类型,因为int可以表示的整数有限,不能满足大数的要求。可以使用字符串来表示大数,模拟大数相加的过程。
思路: 1.反转两个字符串,便于从低位到高位相加和最高位的进位导致和的位数增加;
2.对齐两个字符串,即短字符串的高位用‘0’补齐,便于后面的相加;
3.把两个正整数相加,一位一位的加并加上进位。
示例1:
示例2:
#include <iostream>
#include <string>
using namespace std;
string invert(string &src)
{
string newStr=src;
for(int i=src.length()-1,j=0; i>=0; --i,++j)
newStr[j]=src[i];
return newStr;
}
string intAdd(string &rs1,string &rs2)
{
string str1=invert(rs1);
string str2=invert(rs2);
if(str1.length()<str2.length())
str1.swap(str2);
for(size_t i=0; i!=str2.length(); ++i)
{
char c1=str1[i];
char c2=str2[i];
int t=((int)c1-48)+((int)c2-48);
if(t>=10)
{
//进位
int x=t/10;
t%=10;
size_t n=i+1;
do
{
int t1=(int)str1
-48+x;
if(t1>=10)
{
str1
=(char)(t1%10+48);
++n;
}
else
{
str1
=(char)(t1+48);
}
if(n==str1.length())
{
str1+="1";
break;
}
x=t1/10;
}
while(x!=0);
str1[i]=(char)(t+48);
}
else
{
str1[i]=(char)(t+48);
}
}
string &rstrResult=str1;
string strOut=invert(rstrResult);
return strOut;
}
int main()
{
string s1,s2;
cin>>s1>>s2;
string &rs1=s1,&rs2=s2;
string strResult=intAdd(rs1,rs2);
cout<<strResult<<endl;
system("pause");
return 0;
}
参考资料:
两个大数相加,使用字符串模拟相加过程
用string实现大整数加法
Fibonacci number时,完全蒙了,不知道从何下手,因为普通的思路计算前50个Fibonacci数就比较费时,还没到12位呢!更别说计算含1000位数字的时候是第多少个Fibonacci数了。因此想到这类题肯定有更巧妙的解法,在网上查询了相关资料,发现可以用来string实现大整数的加法。
大数相加不能直接使用基本的int类型,因为int可以表示的整数有限,不能满足大数的要求。可以使用字符串来表示大数,模拟大数相加的过程。
思路: 1.反转两个字符串,便于从低位到高位相加和最高位的进位导致和的位数增加;
2.对齐两个字符串,即短字符串的高位用‘0’补齐,便于后面的相加;
3.把两个正整数相加,一位一位的加并加上进位。
示例1:
#include <iostream> #include <string> using namespace std; #define MAXSIZE 1000 int main() { char number1[MAXSIZE+1]; char number2[MAXSIZE+1]; char sum[MAXSIZE+2]; char temp1[MAXSIZE+1]; char temp2[MAXSIZE+1]; int len1 = 0; int len2 = 0; int i = 0; int j = 0; int maxLen = 0; int nSum = 0; int nCarryBit = 0; int nOverFlow = 0; cin>>number1; cin>>number2; //1.反转字符串,便于从低位到高位相加和最高位的进位导致和的位数增加 len1 = strlen(number1); len2 = strlen(number2); j = 0; for(i = len1-1; i >= 0; --i) { temp1[j++] = number1[i]; } temp1[j] = '\0'; j = 0; for(i = len2-1; i >= 0; --i) { temp2[j++] = number2[i]; } //2.把两个字符串补齐,即短字符串的高位用‘0’补齐 maxLen = (len1 > len2)?len1:len2; if(len1 < len2) { for(i = len1; i < len2; ++i) temp1[i] = '0'; temp1[len2] = '\0'; } else if(len1 > len2) { for(i = len2; i < len1; ++i) temp2[i] = '0'; temp2[len1] = '\0'; } //3.把两个正整数相加,一位一位的加并加上进位 for(i = 0; i < maxLen; i++) { nSum = temp1[i] - '0' + temp2[i] - '0' + nCarryBit; if(nSum > 9) { if(i == (maxLen-1)) nOverFlow = 1; nCarryBit = 1; sum[i] = nSum - 10 + '0'; } else { nCarryBit = 0; sum[i] = nSum + '0'; } } //如果溢出的话表示位增加了 if(nOverFlow == 1) { sum[maxLen++] = nCarryBit + '0'; } sum[maxLen] = '\0'; //从后向前输出,即是相加后的值 for(i = maxLen-1; i >=0; --i) putchar(sum[i]); cout<<"\n"; system("pause"); return 0; }
示例2:
#include <iostream>
#include <string>
using namespace std;
string invert(string &src)
{
string newStr=src;
for(int i=src.length()-1,j=0; i>=0; --i,++j)
newStr[j]=src[i];
return newStr;
}
string intAdd(string &rs1,string &rs2)
{
string str1=invert(rs1);
string str2=invert(rs2);
if(str1.length()<str2.length())
str1.swap(str2);
for(size_t i=0; i!=str2.length(); ++i)
{
char c1=str1[i];
char c2=str2[i];
int t=((int)c1-48)+((int)c2-48);
if(t>=10)
{
//进位
int x=t/10;
t%=10;
size_t n=i+1;
do
{
int t1=(int)str1
-48+x;
if(t1>=10)
{
str1
=(char)(t1%10+48);
++n;
}
else
{
str1
=(char)(t1+48);
}
if(n==str1.length())
{
str1+="1";
break;
}
x=t1/10;
}
while(x!=0);
str1[i]=(char)(t+48);
}
else
{
str1[i]=(char)(t+48);
}
}
string &rstrResult=str1;
string strOut=invert(rstrResult);
return strOut;
}
int main()
{
string s1,s2;
cin>>s1>>s2;
string &rs1=s1,&rs2=s2;
string strResult=intAdd(rs1,rs2);
cout<<strResult<<endl;
system("pause");
return 0;
}
参考资料:
两个大数相加,使用字符串模拟相加过程
用string实现大整数加法
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- 关于指针的一些事情
- c++ primer 第五版 笔记前言
- share_ptr的几个注意点
- Lua中调用C++函数示例
- Lua教程(一):在C++中嵌入Lua脚本
- Lua教程(二):C++和Lua相互传递数据示例
- C++联合体转换成C#结构的实现方法
- C++高级程序员成长之路
- C++编写简单的打靶游戏
- C++ 自定义控件的移植问题
- C++变位词问题分析
- C/C++数据对齐详细解析
- C++基于栈实现铁轨问题
- C++中引用的使用总结
- 使用Lua来扩展C++程序的方法
- C++中调用Lua函数实例
- Lua和C++的通信流程代码实例
- C与C++之间相互调用实例方法讲解
- 解析C++中派生的概念以及派生类成员的访问属性