您的位置:首页 > 编程语言 > C语言/C++

C++ 大数版的加减乘除代码实现总结

2015-10-05 10:39 555 查看
1)大正整数的加法

具体思路就是模仿手算的加法,我在这里先将输入的字符串reverse便于操作,最后去掉结果的前置0即可。注意:如果答案就是0,那么需要特殊处理。

大量的测试数据可以 上交至hdu 1002

[cpp] view
plaincopy

#include<iostream>

#include<string>

#include<algorithm>

using namespace std;

int main()

{

int n;

cin>>n;

int m=0;

int l=0;

for(int i=1;i<=n;i++)

{

string s1,s2,s(10000,'0');

cin>>s1>>s2;

m++;

cout<<(l++?"\n":"");

reverse(s1.begin(),s1.end());

reverse(s2.begin(),s2.end());

for(int j=0;j<s1.length();j++)

s[j]=s1[j];

int temp=0;

for(int k=0;k<s2.length();k++)

{

temp+=s[k]-48+s2[k]-48;

s[k]=temp%10+'0';

temp/=10;

}

s[s2.length()]=s[s2.length()]-48+temp+48;

reverse(s.begin(),s.end());

reverse(s1.begin(),s1.end());

reverse(s2.begin(),s2.end());

cout<<"Case "<<m<<":"<<endl;

cout<<s1<<" + "<<s2<<" = "<<s.substr(s.find_first_not_of('0'))<<endl;



}

return 0;

}

(2)大正整数的减法

同样是模拟手算,处理借位。用大的减去小的,最后再判断是否需要添加负号。

[cpp] view
plaincopy

#include <iostream>

#include <string>

#include <cstring>

#include <vector>

#include <algorithm>

using namespace std;

int strComp(string &s1,string &s2)

{

int len1=s1.length();

int len2=s2.length();

if(len1>len2)

return 0;

else if(len1<len2)

return 1;

else{

if(s1>=s2)

return 0;

else

return 1;

}

}

int main()

{

string s1,s2;

while(cin>>s1>>s2)

{

string s(10000,'0');

bool fgEx=true;

if(strComp(s1,s2)==1)

{

string temp;

temp=s1;

s1=s2;

s2=temp;

fgEx=false;

}

if(s1==s2)

{

cout<<s1<<" - "<<s2<<" = "<<"0"<<endl;

continue;

}

reverse(s1.begin(),s1.end());

reverse(s2.begin(),s2.end());

for(int i=0;i<s1.length();i++)

s[i]=s1[i];

for(int i=0;i<s2.length();i++)

{

if(s[i]>=s2[i])

s[i]=s[i]-'0'-(s2[i]-'0')+'0';

else{

s[i+1]=s[i+1]-'0'-1+'0';

s[i]=s[i]-'0'+10-(s2[i]-'0')+'0';

}

}

if(fgEx==false)

{

reverse(s2.begin(),s2.end());

cout<<s2<<" - ";

reverse(s1.begin(),s1.end());

cout<<s1<<" = ";

reverse(s.begin(),s.end());

cout<<"-"<<s.substr(s.find_first_not_of('0'))<<endl;

}

else

{

reverse(s1.begin(),s1.end());

cout<<s1<<" - ";

reverse(s2.begin(),s2.end());

cout<<s2<<" = ";

reverse(s.begin(),s.end());

cout<<s.substr(s.find_first_not_of('0'))<<endl;

}

}

return 0;



}

(3)大正整数乘法

还是模拟手算,第一个字符串的第i位乘以第二个字符串的第j位一定是结果的第i+j位,如果i+j已经有值,直接加上去就OK,别忘了处理进位。

这样的算法的复杂度是O(n2).利用FFT可以将算法优化到O(nlogn),关于FFT的实现在此不再赘述,可以参考算法导论或者 http://www.cnblogs.com/lsx54321/archive/2012/07/20/2601632.html。同样可提交至poj 2389。

[cpp] view
plaincopy

#include <iostream>

#include <string>

#include <cstring>

#include <vector>

#include <algorithm>

using namespace std;

int main()

{

string s1,s2;

while(cin>>s1>>s2)

{

string s(1000,'0');

reverse(s1.begin(),s1.end());

reverse(s2.begin(),s2.end());

for(int i=0;i<s1.length();i++)

for(int j=0;j<s2.length();j++)

{

int temp=(s1[i]-'0')*(s2[j]-'0');

s[i+j+1]=s[i+j+1]-'0'+(s[i+j]-'0'+temp)/10+'0';

s[i+j]=(s[i+j]-'0'+temp)%10+'0';

}

reverse(s.begin(),s.end());

if(s.find_first_not_of('0')==string::npos)

cout<<"0"<<endl;

else

cout<<s.substr(s.find_first_not_of('0'))<<endl;

}

return 0;

}

(4)大整数除法

我们将除法看作是减法来处理,用被减数不断的减去减数,记录减的次数即是商的值。但是我们当然不能一个一个减,因为如果有10000000/1这种情况不是要减到猴年马月。

我们可以记录被减数和减数的位数之差len,将减数扩大10的len倍。然后依次去减,一旦被减数小于减数时,将减数减小10倍,直至到原值。依次循环,去掉前置0,得出结果。

[cpp] view
plaincopy

#include <iostream>

#include <string>

#include <cstring>

#include <vector>

#include <algorithm>

using namespace std;

int strComp(string &s1,string &s2)

{

int len1=s1.length();

int len2=s2.length();

if(len1>len2)

return 0;

else if(len1<len2)

return 1;

else{

if(s1>=s2)

return 0;

else

return 1;

}

}

string Sub(string s1,string s2)

{

if(strComp(s1,s2)==1)

return "-1";

reverse(s1.begin(),s1.end());

reverse(s2.begin(),s2.end());

string s(1000,'0');

for(int i=0;i<s1.length();i++)

s[i]=s1[i];

for(int i=0;i<s2.length();i++)

{

if(s[i]>=s2[i])

s[i]=s[i]-'0'-(s2[i]-'0')+'0';

else{

s[i+1]=s[i+1]-'0'-1+'0';

s[i]=s[i]-'0'+10-(s2[i]-'0')+'0';

}

}

reverse(s.begin(),s.end());

if(s.find_first_not_of('0')==string::npos)

return "0";

else

return s.substr(s.find_first_not_of('0'));

}

int main()

{

string s1,s2;

while(cin>>s1>>s2)

{

string s(1000,'0');

if(strComp(s1,s2)==1)

{

cout<<"0"<<endl;

continue;

}

int len1=s1.length();

int len2=s2.length();

int dis=len1-len2;

for(int i=0;i<dis;i++)

s2+='0';

string ans(1000,'0');

while(dis>=0)

{

int sum=0;

string temp;

while((temp=Sub(s1,s2))!="-1")

{

sum++;

s1=temp;

}

ans[ans.length()-dis-1]=sum+'0';

dis--;

s2=s2.substr(0,len2+dis);

}

if(ans.find_first_not_of('0')==string::npos)

cout<<"0"<<endl;

else{

string res=ans.substr(ans.find_first_not_of('0'));

cout<<res<<endl;

}

}

return 0;

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