大数运算在面试与笔试中遇到的概率还是蛮大,上次在大华笔试就遇到过。
题目:编写一个关于大整型无符号数的加法、乘法的类。
#include <iostream>
#include <string>
#include <deque>
#include <functional>
#include <algorithm>
using namespace std;
class MyBigNum
{
private:
deque<int> v; //用deque容器表示的大整数
public:
MyBigNum(){}
MyBigNum(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();
}
MyBigNum Add(MyBigNum &m)
{
MyBigNum 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(),end(),m.begin()-n,result.Back_Inserter(),plus<int>());
}
for(int i=-n-1;i>=0;i--)
{
result.push_front(*(m.begin()+i));
}
result.adjust();//结果调整
return result;
}
MyBigNum Multiply(MyBigNum &m)
{
MyBigNum result("0");
MyBigNum mid;
for(int i=0;i<m.size();i++)
{
mid=*this;
for(int j=0;j<i;j++)//加0相当扩大10倍
{
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()
{
MyBigNum m1("1234567890");
MyBigNum m2("99999999998");
MyBigNum result=m1.Add(m2);
cout<<"1234567890+99999999998=";
copy(result.begin(),result.end(),ostream_iterator<int>(cout));
cout<<endl;
MyBigNum m3("99");
MyBigNum m4("99999");
MyBigNum m5=m3.Multiply(m4);
cout<<"99*99999=";
copy(m5.begin(),m5.end(),ostream_iterator<int>(cout));
cout<<endl;
return 0;
}
其实这个程序还存在一个很明显的漏洞,这也是上次大华面试官留给我的一个问题。
其实当两个乘数或加数够大时,他们的相加或相乘的结果会超出栈的表示范围,因些解决办法是将他们用堆存储。