Programming Challenges 习题6.6.1

本文分享了一种使用高精度加法计算斐波那契数列的方法,解决了在大数情况下普通整型无法表示的问题。通过自定义的Less和Greater函数进行大小比较,以及add函数实现字符串形式的大数加法,最终实现了在给定区间内找出斐波那契数列的元素数量。

PC/UVa:110601/10183

How Many Fibs?

做题之前先查了查,发现没人用那个封闭形式估计,所以就高精度加法了,uDebug测试用例调试的时候出了2个小问题:

  • 加法的时候把数字改成小端序了,比较的时候为了用string内置的<运算符,应该换成大端序比较
  • 当数列中的某一项大于a时,也可能会大于b,所以应该先判断,然后再算下一项

另外,题目中求a <= fi <= b,所以专门写了LessGreater

#include <iostream>
#include <string>
#include <vector>

using namespace std;

bool Less(const string &str1, const string &str2)
{
	if (str1.size() < str2.size()) return true;
	else if (str1.size() > str2.size()) return false;
	else{
		string strTmp1(str1.rbegin(), str1.rend()), strTmp2(str2.rbegin(), str2.rend());
		return strTmp1 < strTmp2;
	}
}

bool Greater(const string &str1, const string &str2)
{
	if (str1.size() < str2.size()) return false;
	else if (str1.size() > str2.size()) return true;
	else{
		string strTmp1(str1.rbegin(), str1.rend()), strTmp2(str2.rbegin(), str2.rend());
		return strTmp1 > strTmp2;
	}
}

string add(const string &str1, const string &str2)
{
	size_t i = 0, j = 0;
	string strRet;
	int carry = 0, sum = 0;
	while (i < str1.size() && j < str2.size()){
		sum = str1[i] - '0' + str2[j] - '0' + carry;
		if (sum >= 10){
			sum -= 10;
			carry = 1;
		}
		else carry = 0;
		strRet.push_back(sum + '0');
		i++, j++;
	}
	while (i < str1.size()){
		sum = str1[i] - '0' + carry;
		if (sum >= 10){
			sum -= 10;
			carry = 1;
		}
		else carry = 0;
		strRet.push_back(sum + '0');
		i++;
	}
	while (j < str2.size()){
		sum = str2[j] - '0' + carry;
		if (sum >= 10){
			sum -= 10;
			carry = 1;
		}
		else carry = 0;
		strRet.push_back(sum + '0');
		j++;
	}
	if (carry == 1) strRet.push_back('1');
	return strRet;
}

void calFibs(const string &stra, const string &strb)
{
	string strA(stra.rbegin(), stra.rend()), strB(strb.rbegin(), strb.rend());
	vector<string> vecstrFib;
	string strSum;
	vecstrFib.push_back("0");
	vecstrFib.push_back("1");
	size_t n = 2, begin, end;
	while (1){
		strSum = add(vecstrFib[n - 1], vecstrFib[n - 2]);
		vecstrFib.push_back(strSum);
		n++;
		if (!Less(strSum, strA)){
			begin = n;
			break;
		}
	}
	while (1){
		if (Greater(strSum, strB)){
			end = n;
			break;
		}
		strSum = add(vecstrFib[n - 1], vecstrFib[n - 2]);
		vecstrFib.push_back(strSum);
		n++;
	}
	cout << end - begin << endl;
}

int main()
{
	string stra, strb;
	while (cin >> stra >> strb){
		if (stra[0] == '0' && strb[0] == '0') break;
		calFibs(stra, strb);
	}
	return 0;
}
/*
10 100
1234567890 9876543210
0 0
*/

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值