大数运算在面试与笔试中遇到的概率还是蛮大,上次在大华笔试就遇到过。
题目:编写一个关于大整型无符号数的加法、乘法的类。
#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; }
其实这个程序还存在一个很明显的漏洞,这也是上次大华面试官留给我的一个问题。
其实当两个乘数或加数够大时,他们的相加或相乘的结果会超出栈的表示范围,因些解决办法是将他们用堆存储。