【北大OJ第二题】Exponentiation(C++)

#include "stdafx.h"
#include <string>
#include <stdlib.h>
#include <string>
#include <iostream>
#include <sstream>
#include <time.h>

using namespace std;

string calExponentiation(string base, int exp);
string bigNumberMultiply(string first, string second, int len);
string multiply(string first, string second, int len);
string formatterNumber(string second, int lenMax);
void dealString(string *str, string ac, int len);
string add(string AD, string BC);
void deleteZero(string *str);
void convertIntToString(int value, string *s);
void printResult(string result);

template <class T>
void convertStringToInt(T *, string);

int main() 
{ 
	string base;   //基数
	int exp = 0;   //指数
	string result; //结果
	double temp = 0;
	clock_t t1,t2;

	/* 1. 获取输入信息 */
	while(cin>>base>>exp)
	{
		t1 = clock();
		/* 2.参数控制 */
		convertStringToInt(&temp, base);
		/* 3. 计算结果 */
		result = calExponentiation(base, exp);

		/* 4. 打印结果 */
		printResult(result);
		t2 = clock();
		float diff = ((float)t2 - (float)t1) / CLOCKS_PER_SEC;
		cout << diff << endl;
	}
	return 0;    
} 

/* 计算结果 */
string calExponentiation(string base, int exp)
{
	int temp = exp;
	string resultTemp = base;

	if (1 == exp)
	{
		return base;
	}
	else
	{
		resultTemp = calExponentiation(base, exp/2);
		resultTemp = bigNumberMultiply(resultTemp, resultTemp, resultTemp.size());
		deleteZero(&resultTemp);

		if (0 != exp % 2)
		{
			resultTemp = bigNumberMultiply(resultTemp, base, resultTemp.size());
			deleteZero(&resultTemp);
		}
	}

	return resultTemp;
}

/* 计算两个大数相乘 */
string bigNumberMultiply(string first, string second, int len)
{
	int dotIndex1 = 0;
	int dotIndex2 = 0;
	int pointPos = 0;
	string result;

	/* 1. 找到小数点的位置 */
	if (-1 != first.find('.', 0))
	{
		dotIndex1 = first.size() - first.find('.', 0) - 1;
		dotIndex2 = second.size() - second.find('.', 0) - 1;
		/* 记录计算结果小数点的位置 */
		pointPos = dotIndex1 + dotIndex2;
	}
	else
	{
		/* 输入的是整数,没有小数点 */
		pointPos = -1;
	}

	/* 如果有小数点的话,去除数小数点 */
	if (-1 != pointPos)
	{
		first.erase(first.size() - dotIndex1 - 1, 1);
		second.erase(second.size() - dotIndex2 - 1, 1);
		result = multiply(first, second, len - 1);
	}
	else
	{
		result = multiply(first, second, len);
	}

	if (-1 == pointPos)
	{
		deleteZero(&result);
	}

	if (-1 != pointPos)
	{
		if (result.size() < pointPos)
		{
			result.insert(0, pointPos - result.size(), '0');
		}
		result.insert(result.size() - pointPos, 1, '.');
		if ('0' != result[0])
		{
			result.insert(0, 1, '0');
		}
	}

	return result;
}

/* 整数乘法,去除了小数点的乘法 */
string multiply(string first, string second, int len)
{
	string result;
	int len1 =  0;
	int len2 = 0;
	int temp1 = 0;
	int temp2 = 0;
	string stringTemp;

	/* 1.高位补零,使得两个数的位数相同 */
	first = formatterNumber(first, len);
	second = formatterNumber(second, len);

	/* 2.少于4位数,可以直接计算 */
	if (4 >= len)
	{
		convertStringToInt(&temp1, first);
		convertStringToInt(&temp2, second);
		convertIntToString(temp1 * temp2, &stringTemp);
		result += stringTemp;
		return result;
	}

	/* 3.将first和second分别对半成两部分 */
	len1 = len / 2;
	len2 = len - len1;
	string A = first.substr(0, len1);
	string B = first.substr(len1);
	string C = second.substr(0, len1);
	string D = second.substr(len1);

	/* 4.乘法法则,分块处理 */
	int lenMax = max(len1, len2);
	string AC = multiply(A, C, len1);
	string AD = multiply(A, D, lenMax);
	string BC = multiply(B, C, lenMax);
	string BD = multiply(B, D, len2);

	/* 5.处理BD,得到原位和进位 */
	string sBD[] = {"", ""};
	dealString(sBD, BD,len2);

	/* 6.处理AD+BC的和 */
	string ABCD = add(AD, BC);

	/* 如果BD有进位的话,加上BD的进位 */
	if ("0" != sBD[1])
	{
		ABCD = add(ABCD, sBD[1]);
	}

	/* 7.得到ACBD的进位 */
	string sABCD[] = {"", ""};
	dealString(sABCD, ABCD, lenMax);

	/* 8.AC加上ADBC的进位 */
	AC = add(AC, sABCD[1]);

	result = AC + sABCD[0] + sBD[0];

	return result;

}

string add(string AD, string BC)
{
	string str = "";
	int lenMax = max(AD.size(),BC.size());
	AD = formatterNumber(AD, lenMax);
	BC = formatterNumber(BC, lenMax);
	int flag = 0;
	int temp1 = 0;
	int temp2 = 0;
	string stringTemp;

	for (int i = lenMax - 1; i >= 0; i--)
	{
		convertStringToInt(&temp1, AD.substr(i, 1));
		convertStringToInt(&temp2, BC.substr(i, 1));
		int t = flag + temp1 + temp2;

		// 如果结果超过9,则进位当前位只保留个位数
		if (t > 9)
		{
			flag = 1;
			t = t - 10;
		}
		else
		{
			flag = 0;
		}

		// 拼接结果字符串
		convertIntToString(t, &stringTemp);
		str = stringTemp + str;
	}
	if (flag != 0)
	{
		convertIntToString(flag, &stringTemp);
		str = stringTemp + str;
	}
	return str;
}
void dealString(string *str, string ac, int len)
{
	str[0] = ac;
	str[1] = "0";
	if (len < ac.size())
	{
		int t = ac.size() - len;
		str[0] = ac.substr(t);
		str[1] = ac.substr(0, t);
	}
	else
	{
		string result = str[0];
		for (int i = result.size(); i < len; i++)
		{
			result = "0" + result;
		}
		str[0] = result;
	}
}
string formatterNumber(string second, int lenMax)
{
	while (lenMax > second.length())
	{
		second = "0" + second;
	}
	return second;
}

/* 打印计算结果,主要处理结果中的0元素问题 */
void printResult(string result)
{
	int dotIndex1 = result.find('.', 0);

	/* 1.删除结果前面无用的0元素 */
	deleteZero(&result);

	/* 2.删除末尾的0 */
	if (-1 != dotIndex1)
	{		
		int len = result.size();
		while ('0' == result[len - 1])
		{
			result.erase(len - 1, 1);
			len--;
		}
	}

	/* 3.打印结果 */
	cout << result << endl;
}

void deleteZero(string *str)
{
	for (int i = 0; i < str->size(); i++)
	{
		if ('0' == str->at(0))
		{
			str -> erase(0, 1);
		}
		else
		{
			/* 找到第一个非0的数则跳出循环 */
			break;
		}
	}
}

template <class T>
void convertStringToInt(T *pValue, string s)
{
	stringstream ss(s);
	ss >> *pValue;
}

void convertIntToString(int value, string *s)
{
	stringstream ss;
	ss << value;
	*s = ss.str();
}


超时了,哎,不想多写了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值