大数运算

大数运算在面试与笔试中遇到的概率还是蛮大,上次在大华笔试就遇到过。

题目:编写一个关于大整型无符号数的加法、乘法的类。

#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; }

  其实这个程序还存在一个很明显的漏洞,这也是上次大华面试官留给我的一个问题。

      其实当两个乘数或加数够大时,他们的相加或相乘的结果会超出栈的表示范围,因些解决办法是将他们用堆存储。

      

原文地址:https://www.cnblogs.com/danshui/p/2508337.html