大数四则运算--vector模拟超级大数

    之前用vector写过大数的运算,思路就是将每个位置的数字都放进vector中,然后模拟进行运算。这样的话,效率比较高,但是却不是最高的。其实可以不是每次存储每个位置的数字,而是一次存储多位。例如,使用vector一次存储四位数,vector<int> ve={12, 3456, 7890, 123}这个代表的数字就是123789034560012。此思路肯定比每一位存储的效率更高一些,占用空间也稍微少一些。

void func_sub(vector<int> &veOne, vector<int> &veTwo, vector<int> &veRes)
{
	veRes.clear();
	int i, j;
	int iCarry = 0;
	for (i = 0, j = 0; i < veOne.size() && j < veTwo.size(); ++i, ++j)
	{
		int iTmpValue = veOne[i] - iCarry - veTwo[j];
		if (iTmpValue < 0)
		{
			iCarry = 1;
			iTmpValue += 10000; //写死的,因为是四位数
		}
		else
			iCarry = 0;
		veRes.push_back(iTmpValue);
	}
	if (j < veTwo.size())  //出错,要求第一个数必须大于第二个
	{
		cout << "error onevalue < twovalue" << endl;
		return;
	}
	while (i < veOne.size())  //第一个数剩下的数字顺位放进来
	{
		if (iCarry)  //有借位
		{
			if (veOne[i] < iCarry) //极端情况,例如10000000001
				veRes.push_back(10000 - veOne[i]);
			else
			{  //正常情况
				veRes.push_back(veOne[i] - iCarry);
				iCarry = 0;
			}
		}
		else
			veRes.push_back(veOne[i]);
		i++;
	}
}
void func_add(vector<int> &veOne, vector<int> &veTwo, vector<int> &veRes)
{
	veRes.clear();
	int iOne, iTwo;
	int iCarry = 0;
	for (iOne = 0, iTwo = 0; iOne < veOne.size() && iTwo < veTwo.size(); iOne++, iTwo++)
	{
		int iTmpValue = veOne[iOne] + veTwo[iTwo] + iCarry;
		if (iTmpValue >= 10000)
		{
			veRes.push_back(iTmpValue - 10000);
			iCarry = iTmpValue / 10000;
			if (iCarry >= 2)  //出错
			{
				cout << "error iCarry == 2" << endl;
				return;
			}
		}
		else
			veRes.push_back(iTmpValue);
	}
	while (iOne < veOne.size())
	{
		veRes.push_back(veOne[iOne++] + iCarry);
		iCarry = 0;
	}
	while (iTwo < veTwo.size())
	{
		veRes.push_back(veTwo[iTwo++] + iCarry);
		iCarry = 0;
	}
}
void func_mul(vector<int> &veOne, vector<int> &veTwo, vector<int> &veRes)
{
	veRes.clear();
	int iCarry = 0;
	int iOne, iTwo;
	int i;
	veRes.resize(veOne.size() + veTwo.size());
	//模拟乘法的规则
	for (iOne = 0, iTwo = 0; iOne < veOne.size(); iOne++)
	{
		int iTmpValue = 0;
		i = iOne;
		for (iTwo = 0; iTwo < veTwo.size(); ++iTwo)  
		{
			iTmpValue = veOne[iOne] * veTwo[iTwo] + iCarry;
			veRes[i] += iTmpValue;
			iCarry = veRes[i] / 10000;
			veRes[i++] %= 10000;
		}
		if (iCarry)
		{
			veRes[i] += iCarry;
			iCarry = 0;
		}
	}
	veRes[i] += iCarry;
	if (veRes[i] >= 10000)  //处理最后一个位置有进位的情况
	{
		veRes[i+1] = veRes[i] / 10000;
		veRes[i] = veRes[i] % 10000;
	}
}
void divtwo(vector<int> &veOne, vector<int> &veTwo) //除2
{
	veTwo.clear();
	int iLen = veOne.size() - 1;
	int iCarry = 0;
	while (iLen >= 0 && veOne[iLen] == 0)
		iLen--;
	while (iLen >= 0)
	{
		if ((iLen == 0) && (veOne[iLen] < 2) && (iCarry = 0))
			veOne.push_back(0);
		else 
		{
			if (veOne[iLen] < 2)
			{
				iCarry = 1;
			}
			else
			{
				if (iCarry == 1)
				{
					veTwo.push_back((veOne[iLen] + 10000) / 2);
					iCarry = 0;
				}
				else
					veTwo.push_back(veOne[iLen] / 2);
			}
		}
		iLen--;
	}
}
int veccompare(vector<int> &veOne, vector<int> &veTwo) //比较,大于 1,等于 0,小于 -1,其他 出错
{
	int iOne = veOne.size()-1;
	int iTwo = veTwo.size()-1;
	//保证头部的0不影响比较结果
	while (iOne >= 0 && veOne[iOne] == 0)
		iOne--;
	while (iTwo >= 0 && veTwo[iTwo] == 0)
		iTwo--;
	if (iOne > iTwo)
		return 1;
	else if (iOne < iTwo)
		return -1;
	while (iOne >= 0 && iTwo >= 0)
	{
		if (veOne[iOne] > veTwo[iTwo])
			return 1;
		else if (veOne[iOne] < veTwo[iTwo])
			return -1;
		iOne--;
		iTwo--;
	}
	return 0;
}
void func_div(vector<int> &veOne, vector<int> &veTwo, vector<int> &veRes)
{
	//借助乘法来运算除法,以被除数为基准,每次乘二找到最后的商
	int iRightBefor = 0, iRight = 0, iLeftBefor = 0, iLeft = 0;
	vector<int> veTmp = { 1 };
	func_mul(veTwo, veTmp, veRes);
	vector<int> veLeft, veRight, veBefore;
	while (true)
	{
		veBefore = veRes;
		vector<int> veNum;
		func_mul(veTwo, veRes, veNum);
		if (veccompare(veOne, veNum) == 1)  //继续乘二
		{
			veLeft = veRes;
			vector<int> veTmp;
			if (!veRight.size())
			{
				func_add(veRes, veTwo, veTmp);
				divtwo(veTmp, veRes);
			}
			else
			{
				func_add(veRes, veRight, veTmp);
				divtwo(veTmp, veRes);
			}
			//veRight = veRes;
		}
		else if (veccompare(veOne, veNum) == 0)  //返回
		{
			return;
		}
		else if (veccompare(veOne, veNum) == -1)  //需要寻找新的值
		{
			veRight = veRes;
			vector<int> veTmp;
			if (!veLeft.size())
			{
				veTmp = veRes;
				divtwo(veTmp, veRes);
			}
			else
			{
				func_add(veRes, veLeft, veTmp);
				divtwo(veTmp, veRes);
			}
			//veLeft = veRes;
		}
		else
		{
			cout << "error" << endl;
			return;
		}
		//是否除不尽,除不尽时,获取当前值和当前值的大1的值进行比较
		vector<int> vec;
		vector<int> veTmp1 = { 1 };
		func_add(veRes, veTmp1, vec);
		vector<int> veMul, veMul2;
		func_mul(vec, veTwo, veMul);  //当前值的大一位的值
		func_mul(veRes, veTwo, veMul2);  //当前值
		if (veccompare(veOne, veMul) == -1 && (veccompare(veOne, veMul2) == 1))
		{
			//确定是除不尽,去掉尾数返回
			return;
		}
		cout << veRes[0] << endl;
	}
}
void func_print(vector<int> &veRes)
{
	int iLen = veRes.size() - 1;
	while (veRes[iLen] == 0)  //因为乘法可能在头部有多余的空位,那么就会填充0,去掉头部的0
	{
		iLen--;
	}
	for (int i = iLen; i >= 0; --i)
	{
		if (i == iLen);
		else
		{   
			if (0 <= veRes[i] && veRes[i] < 10)
				cout << "000";
			else if (10 <= veRes[i] && veRes[i] < 100)
				cout << "00";
			else if (100 <= veRes[i] && veRes[i] < 1000)
				cout << "0";
		}
		cout << veRes[i];
	}
	cout << endl;
}
int main()
{
	vector<int> veOne = { 144,1293};
	vector<int> veTwo = { 111, 12};
	vector<int> veRes;
	cout << "sub:-   add:+   mul:*   div:/" << endl;
	char ch;
	cin >> ch;
	switch (ch)
	{
	case '-':
		func_sub(veOne, veTwo, veRes);
		break;
	case '+':
		func_add(veOne, veTwo, veRes);
		break;
	case '*':
		func_mul(veOne, veTwo, veRes);
		break;
	case '/':
		func_div(veOne, veTwo, veRes);
		break;
	default:
		cout << "cin error" << endl;
	}
	func_print(veRes);
	return 0;
}

加减乘,三个测试没有问题。除法目前是看命。。。有时候可以运行正确,有时候就死循环。先这样吧,有空再看看。

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值