编一个关于大整型无符号数加法、乘法的类。
大整型数一般是4个字节,但一般会遇到超大数的运算,那么系统提供的int、long就不够用了。因此,必须自定义大整型类,代码如下所示。
(1)如何建立及描述大整型数。一个方案是通过字符串输入建立,通过解析字符串,把每位存入STL提供的容器中。由于会遇到进位问题,即对容器头进行进位插入操作,从这一点看deque<int>双端队列更好。
(2)关于大整形的加法算法,即类中的Add函数。
定义结果大整型变量result
求被加数位与加数位数差n
if n>=0 then
从高位开始,加数所有位与被加数对应为相加,每位结果和存入result后面
把被加数多余位存入result前面
else
从高位开始,被加数所有位与加数对应为相加,每位结果和存入result后面
把加数多余位存入result前面
endif
result <- result.adjust(),进行位数值调整,保证result容器每位值都小于10
返回给result给调用者
类中adjust函数进行大整型数位置调整,保证每位小于10。用表意形式说明如下:设mybignum1 = {9,9},mybignum2 = {8,8},经过上述Add函数1-9步结果为mybignum result = { 17,17},两位数都大于10,因此必须调用adjust调整函数,使最终结果为result = {1,8,7}。adjust算法如下
获得待调整大整型数容器的长的nsize
for 从最低位开始到次高位,循环依次调整每一位
若当前值小于10,转到2
当前位的值等于当前值对10取余
利用while循环把进位值依次加到前面位的值中
end for
if 最高位置大于10
最高位值等于当前值对10取余
改变容器的大小,利用while循环把进位值依次填充新加位的值
endif
(3)关于大整形的乘法算法,即类中的Multiply函数。用表意形式说明如下:设mybignum1 = {1,2,3,4},mybignum2 = {5,6,7},mybignum3 = mybignum1 * mybignum2 = {1,2,3,4} * 7 + {1,2,3,4,0} * 6 + {1,2,3,4,0,0} * 5。即被乘数后面补充适当的0后与乘数每位向乘后再相加。adjust算法如下
定义结果大整型数result,初始值为0,用于累加
定义临时大整型数变量mid
for i=0,i<乘数位数,i++
mid <-- 被乘数大整型数
mid尾部添加适当个数0元素
mid中每位值等于mid中每位当前值乘以乘数从低位开始的第i位数
result <--mid.add(result)
end for
返回result给调用者
代码
# include<iostream>
# include <string>
# include <deque>
# include <functional>
# include <algorithm>
# include<iterator>
using namespace std;
class mybigdata
{
deque<int> v; //用deque容器表示大整数
public:
mybigdata() {}
mybigdata(string strnum) //通过字符串建立大整数
{
copy(strnum.begin(),strnum.end(), back_inserter(v));
transform(v.begin(),v.end(),v.begin(),bind2nd(minus<int>(), '0')); //字符‘1’变成1要减去‘0’
}
deque<int>::iterator begin() //开始迭代指针
{
return v.begin();
}
deque<int>::iterator end() //迭代止指针
{
return v.end();
}
int size() //容器大小
{
return v.size();
}
back_insert_iterator<deque<int> >Back_Inserter()
{
return back_inserter(v);
}
void push_front(int n) //前插入元素
{
v.push_front(n);
}
void push_back(int n) //后插入元素
{
v.push_back(n);
}
void adjust() //调整使容器的每位整型元素值都小于10
{
int nsize = v.size();
for (int i = nsize - 1; i >= 1; --i)
{
int value = v[i];
if (value < 10)
continue;
v[i] = value % 10;
v[i - 1] += value/10;
}
int value = v[0]; //处理最高位
if (value >= 10)
{
v[0] = value % 10;
value = value / 10;
while (value > 0)
{
v.push_front(value % 10);
value /= 10;
}
}
nsize = v.size();
}
mybigdata add(mybigdata&m)
{
mybigdata result;
int n = size() - m.size();
if (n >= 0) //大于等于加数位数
{
transform(begin() + n, end(), m.begin(), result.Back_Inserter(), plus<int>());
for (int i = n - 1; i >= 0; i--)
{
result.push_front(*(begin()+i));
}
}
else
{
//小于加数位数
transform(begin() + n, end(), m.begin()-n, result.Back_Inserter(), plus<int>());
for (int i = -n - 1; i >= 0; i--)
{
result.push_front(*(begin() + i));
}
}
result.adjust(); //结果调整
return result;
}
mybigdata mutiply(mybigdata &m)
{
mybigdata result("0");
mybigdata mid;
for (int i = 0; i < m.size(); i++)
{
mid = *this;
for (int j = 0; j < i; j++) //加0相等于扩大十倍
{
mid.push_back(0);
}
transform(mid.begin(),mid.end(),mid.begin(),bind2nd(multiplies<int>(),*(m.begin()+i)));//被乘数分别乘以每一位乘数
result = mid.add(result); //分项之和累加
}
return result;
}
};
int main()
{
mybigdata m1("1234567890");
mybigdata m2("9999999998");
mybigdata result = m1.add(m2);
cout << "1234567890+9999999998 = ";
copy(result.begin(),result.end(),ostream_iterator<int> (cout));
cout << endl;
mybigdata m3("999");
mybigdata m4("99999");
mybigdata m5 = m3.mutiply(m4);
cout << "999 * 99999 = ";
copy(m5.begin(), m5.end(), ostream_iterator<int>(cout));
cout << endl;
return 0;
}
运行结果