如题,利用非递归办法解决a(n) = r1*a(n-1) + r2*a(n-2)问题。其中斐波那契数列即为r1 = r2 = a1 = a2 = 1的特例。
函数支持两种版本的调用,一种是完全版,一种是简洁版。完全版需要5个参数r1 r2 a1 a2 n,简洁版只需要一个参数n。具体使用方法见代码注释。
/**//*********************************************************************************
*名称:LHRODT.h
*版本号:0.1
*作者:赵耀(中山大学2010级)
*时间:2011.4.4
*简介:
* linear homogeneous relation of degree two的计算函数.形如:
* a(n) = r1*a(n-1) + r2*a(n-2)
* 这样的递归数列,只需调用函数
* LHRODT( r1, r2, a1, a2, n )
* 即可返回数列的第a(n)项(r1,r2,a1,a2均为double类型,n为int类型,返回类型为double).
* 这里r1,r2为公式中r1,r2,而a1,a2为数列的头两项,n为第几项.函数带缓存功能,即第一次
* 调用后,下次调用可以只输入
* LHRODT( n )
* .
*
*未完成特性:
* 1.不含有数据检测功能,如果输入的数据无解,则会返回0.
* 2.简洁版的调用不包含条件检测机制,如果不满足条件依然会调用,但是返回0.
* 3.未含有范围检测功能,如果数据函数结果增长很快,有可能出现数据溢出而没有任何提示.
*已知bug:
* 1.无法处理无解数据的输入.
* 2.简洁版在未调用完全版或者完全版调用失败的情况下只返回0.
* 3.可能在没有任何提示的情况下出现数据溢出.
*版权信息:
* 该代码为开源代码,原作者保留其所有权.你可以拷贝,修改,使用该代码,但是请保留必
* 要的版权信息.
*********************************************************************************/
#ifndef LHRODT_H
#define LHRODT_H
#include <cmath>
using std::pow;
class fsLHRODT //fs = function support
{
public:
fsLHRODT();
double operator()( double, double, double, double, int );
double operator()( int );
private:
double x1; //x1 x2 u1 u2 det 均为计算过程的中间变量
double x2; //result 为最后结果的临时储存
double u1;
double u2;
double det;
double result;
bool flag; //标记完全版的函数是否被调用过
};
fsLHRODT::fsLHRODT()
: x1( 0 ), x2( 0 ), u1( 0 ), u2( 0 ), det( 0 ), result( 0 ), flag( false )
{
}
double fsLHRODT::operator()( double r1, double r2, double a1, double a2, int n )
{
flag = true;
det = r1*r1 + 4*r2;
if ( det < 0 ) //det小于0说明输入的数据不合法,不能按照公式计算,并且下次不能直接调用简洁版函数
{
flag = false;
return 0;
}
else if ( det > 0 )
{
det = sqrt( det );
x1 = ( r1 + det ) / 2;
x2 = ( r1 - det ) / 2;
u1 = ( a1*x2 - a2 ) / ( x1*( x2 - x1 ) );
u2 = ( a2*x1 - a1 ) / ( x2*( x1 - x2 ) );
result = u1*pow( x1, n ) + u2*pow( x2, n );
return result;
}
else
{
x1 = r1 / 2;
u2 = ( a2 - x1*a1 ) / x1*x1;
u1 = a1 / x1 - u2;
result = ( u1 + u2*n ) * pow( x1, n );
return result;
}
}
double fsLHRODT::operator()( int n )
{
if ( flag )
{
if ( det < 0 )
return 0;
else if ( det > 0 )
{
result = u1*pow( x1, n ) + u2*pow( x2, n );
return result;
}
else
{
result = ( u1 + u2*n ) * pow( x1, n );
return result;
}
}
else
return 0;
}
fsLHRODT LHRODT;
#endif