如題,利用非遞歸辦法解決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