大数加减乘除?
大数加减代码:(贴代码)//Bignumber.h #ifndef __BIGNUMBER_H
#define __BIGNUMBER_h
#include <string>
using namespace std;
string bigadd(string s1,string s2);
string bigsub(string s1,string s2);
bool compareS1S2(string s1,string s2);
#endif
//Bignumber.cc #include "Bignumber.h"
bool compareS1S2(string s1,string s2) //比较s1 s2绝对值大小;
{
int len1 = s1.size();
int len2 = s2.size();
int com1=0,com2 = 0;
if (s1[0] == '-')
com1 = 1;
if (s2[0] == '-')
com2 = 1;
if ((len1-com1+1) != (len2-com2+1))
{
return (len1 - com1 + 1) > (len2 - com2 + 1);
}
else
{
while (com1<len1 && com2<len2 && s1[com1] == s2[com2])
{
++com1;
++com2;
}
if (com1 < len1)
{
return s1[com1]>s2[com2];
}
else
{
return true;
}
}
}
string bigadd(string s1,string s2)
{
//判断输入合法性,尚未检查字符串内容
int len1 = s1.size();
int len2 = s2.size();
if (len1 == 0)
return s2;
if (len2 == 0)
return s1;
bool isNagative = false;
string res = "-";
//检测起首
if (s1[0] == '-')
{
if (s2[0] == '-')
{
isNagative = true;
return res + bigadd(s1.substr(1),s2.substr(1));
}
else
{
return bigsub(s2,s1.substr(1));
}
}
else
{
if (s2[0] == '-')
{
return bigsub(s1,s2.substr(1));
}
else
{
if (len1 < len2) //使得len1>=len2
{
return bigadd(s2,s1);
}
int jinwei = 0;
int add1 = len1-1,add2 = len2-1;
string res(len1,0);
while (add2 >= 0)
{
int sum = s1[add1]-'0' + s2[add2]-'0' + jinwei;
res[add1] = sum % 10+'0';
jinwei = sum >= 10 ? 1 : 0;
add2--;
add1--;
}
while (add1 >= 0)
{
int sum = s1[add1]-'0'+ jinwei;
res[add1] = sum % 10+'0';
jinwei = sum >= 10 ? 1 : 0;
add1--;
}
if (jinwei == 1)
{
string jia("1");
return jia + res;
}
else
{
return res;
}
}
}
}
string bigsub(string s1,尚未检查字符串内容
int len1 = s1.size();
int len2 = s2.size();
string fu("-");
if (len1 == 0)
{
return fu + s2;
}
if (len2 == 0)
return s1;
//保障s1>=s2
if (!compareS1S2(s1,s2))
{
string resopsi = bigsub(s2,s1);
if (resopsi[0] == '-')
return resopsi.substr(1);
else
return fu + resopsi;
}
if (s1[0] == '-')
{
if (s2[0] == '-')
{
string tmp1 = bigsub(s1.substr(1),s2.substr(1));
return fu + tmp1;
}
else
{
string tmp2 = bigadd(s1.substr(1),s2);
return fu + tmp2;
}
}
else
{
if (s2[0] == '-')
{
string tmp3 = bigadd(s1,s2.substr(1));
return tmp3;
}
else
{
string res(len1,0);
int sub1 = len1 - 1,sub2 = len2 - 1;
int que = 0;
while (sub2 >= 0)
{
int sum = s1[sub1] - s2[sub2] - que;
res[sub1] =(sum+10) % 10 + '0';
que = (sum >= 0 ? 0 : 1);
--sub1;
--sub2;
}
while (sub1 >= 0)
{
int sum = s1[sub1]-'0' - que;
res[sub1] = (sum+10) % 10 + '0';
que = (sum >= 0 ? 0 : 1);
--sub1;
}
//出去开头的0
int index = 0;
while (res[index] == '0')index++;
if (index == 0)
return res;
else
return res.substr(index);
}
}
}
写代码中的心得: 一开始我以为-1%10=9,后来调试才发现为-1。。。其实还是自己太菜不熟悉。。 大数乘法乘积是逐位相乘,也就是aibj,结果加入到积C的第i+j位,最后处理进位即可,例如:A =17 = 1*10 + 7 = (7,1)最后是十进制的幂表示法,幂次是从低位到高位,以下同。B=25 = 2*10 + 5 = (5,2);C = A * B = (7 * 5,1 * 5 + 2 * 7,1 * 2) = (35,19,2) = (5,22,2. 4)=425。 #ifndef __BIGNUMBER_H
#define __BIGNUMBER_h
#include <string>
#include <vector>
using namespace std;
bool compareS1S2(string s1,string s2);
string bigmul(string s1,string s2);
#endif
//仍然在Bignumber.cc bool compareS1S2(string s1,string s2) //比较s1 s2绝对值大小;
{
int len1 = s1.size();
int len2 = s2.size();
int com1=0,com2 = 0;
if (s1[0] == '-')
com1 = 1;
if (s2[0] == '-')
com2 = 1;
if ((len1-com1+1) != (len2-com2+1))
{
return (len1 - com1 + 1) > (len2 - com2 + 1);
}
else
{
while (com1<len1 && com2<len2 && s1[com1] == s2[com2])
{
++com1;
++com2;
}
if (com1 < len1)
{
return s1[com1]>s2[com2];
}
else
{
return true;
}
}
}
void invertToVector(string s,vector<int>& vec)
{
int siz = s.size();
if (siz == 0)
return;
vec.resize(siz,0);
int i = 0,k=siz-1;
while (i < siz)
{
vec[i] = s[k]-'0';
--k;
++i;
}
}
string invertToString(vector<int>& vec)
{
int siz = vec.size();
if (siz == 0)
{
string s("");
return s;
}
string s(siz,k = siz - 1;
while (i < siz)
{
s[k] = vec[i]+'0';
--k;
++i;
}
//去0
int index = 0;
while (s[index] == '0')++index;
if (index == 0)
return s;
else
return s.substr(index);
}
string bigmul(string s1,string s2)
{
vector<int> v1,v2;
invertToVector(s1,v1);
invertToVector(s2,v2);
int len1 = s1.size(),len2 = s2.size();
vector<int> res(len1 + len2,0);
for (int k = 0; k < len1 + len2; ++k)
{
res[k] = 0;
for (int i = 0; i < len1 && (k - i >= 0); ++i)
{
if (k - i < len2)
{
res[k] += v1[i] * v2[k - i];
}
}
}
int jinwei = 0;
for (int i = 0; i < len1 + len2; ++i)
{
jinwei = res[i] + jinwei;
res[i] = jinwei % 10;
jinwei = jinwei / 10;
}
string ress = invertToString(res);
return ress;
}
大数除法大数除法,应该算是四则运算里面最难的一种了。不同于一般的模拟,除法操作步数模仿手工除法,而是利用减法操作实现的。 根据这个思想,不难写出下面的代码。 #ifndef __BIGNUMBER_H
#define __BIGNUMBER_h
#include <string>
#include <vector>
using namespace std;
string bigadd(string s1,string s2);
string bigdiv(string s1,string s2); //s1/s2
#endif
//Bignumber.cc //会用到 bigsub 函数
string bigdiv(string s1,string s2)
{
int len1 = s1.size();
int len2 = s2.size();
if (len1 < len2)
{
string res("0");
return res;
}
string res(len1 - len2 + 1,0);
string subed(len1 - len2,0+'0');
int index = 0;
int ind = 0;
string tmp(s1);
while (ind<len1-len2+1)
{
string s2s2;
if (index < len1 - len2)
{
s2s2 = s2 + subed.substr(index);
}
else
{
s2s2 = s2;
}
int val = 0;
while (compareS1S2(tmp,s2s2))
{
tmp = bigsub(tmp,s2s2);
++val;
}
res[ind] = val + '0';
++index;
//subed = subed.substr(1);
++ind;
}
//去0
int k = 0;
while (res[k] == '0') ++k;
if (k == 0)
return res;
else
return res.substr(k);
}
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |