C++计算斐波拉西数列高次项,数组实现高精度数的加法

     斐波拉西数列一般最简单想到的就是递归来解决,暴力递归法时间复杂度为O(2^n),这种时间复杂度在项数n比较大的时候就计算不了了,反而直接使用循环时间复杂度为O(n)。但是还有一个问题,斐波拉西数列高次项十分大,比如第一百项的大小为218922995834555169026(设第一项为0)。这么大的数计算机变量无法直接存储,使用科学计数法也会因为精度问题导致不够准确。所以需要解决的问题是大数的存储以及计算。这里使用数组来存储数字即可,数组的每一个元素存储数字的一位。这里使用c++提供的vector容器,比较方便。

#include <iostream>
#include <vector>
using namespace std;

int min(int a, int b) {
	if (a > b) { return b; }
	else { return a; }
}

vector<int> Vadd(vector<int> v1, vector<int> v2) {
	vector<int> result;  // 存放加和结果
	int length1 = v1.size();  // 长度
	int length2 = v2.size();
	int len = min(length1, length2);  // 找最短的那个
	int carry = 0;  // 进位
	for (int i = 0; i < len; i++) {  // 加和前面长度相同的部分
		int add_temp = v1[i] + v2[i] + carry;  // 当前要加的大小
		if (add_temp < 10) {  // 小于10不产生进位
			result.push_back(add_temp);  // 直接加
			carry = 0;
		}
		else {
			result.push_back(add_temp % 10);  // 产生进位,加模的余数
			carry = 1;  // 进位变成1
		}
	}
	// 同样的方法加和后面相同的部分
	if (carry == 1) {
		if (length1 == length2) {
			result.push_back(1);
		}
		else if (len == length1) {
			int carry2 = 1;
			for (int i = length1; i < length2; i++) {
				int add_temp2 = v2[i] + carry2;
				if (add_temp2 < 10) {
					result.push_back(add_temp2);
					carry2 = 0;
				}
				else {
					result.push_back(add_temp2 % 10);
					carry2 = 1;
				}
			}
			if (carry2 == 1) {
				result.push_back(1);
			}
		}
		else {
			int carry2 = 1;
			for (int i = length2; i < length1; i++) {
				int add_temp2 = v1[i] + carry2;
				if (add_temp2 < 10) {
					result.push_back(add_temp2);
					carry2 = 0;
				}
				else {
					result.push_back(add_temp2 % 10);
					carry2 = 1;
				}
			}
			if (carry2 == 1) {
				result.push_back(1);
			}
		}
	}
	else {
		if (len = length1 && length1 != length2) {
			for (int i = length1; i < length2; i++) {
				result.push_back(v2[i]);
			}
		}
		else if (len = length2 && length1 != length2) {
			for (int i = length2; i < length1; i++) {
				result.push_back(v1[i]);
			}
		}
	}
	return result;
}

void fibo(int n, vector<vector<int>>& storage) {
	if (n > 1) {
		for (int i = 2; i <= n - 1; i++) {
			storage.push_back(Vadd(storage[i - 2], storage[i - 1]));
		}
	}
}

void printV(vector<int> v) {
	int len = v.size();
	// vector容器最低位存储的是个位,所以打印需要从后往前打印
	for (int i = len - 1; i >= 0; i--) {
		cout << v[i];
	}
	cout << endl;
	cout << endl;
}

int main() {
	vector<vector<int>> storage;
	vector<int> v0; v0.push_back(0);
	vector<int> v1; v1.push_back(1);
	storage.push_back(v0);
	storage.push_back(v1);
	fibo(100, storage);  // 这里是项数
	int len = storage.size();
	for (int i = 0; i < len; i++) {
		cout << "第" << i + 1 << "项为:";
		printV(storage[i]);
	}
	/*printV(storage[len - 1]);*/
}

        这个代码在vector加法函数也有个优化的地方,上面的代码是先加两个数相同长度的部分,然后再去处理较长的数剩余的部分,实际上将较短的数填充0后使其长度和较长的数相同就不需要后面的步骤了。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值