ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

用Delphi快速计算斐波那契(Fibonacci)数列中的第n个数

2022-02-24 14:02:23  阅读:266  来源: 互联网

标签:begin end Delphi Value TMatrix2 斐波 Fibonacci const Result


本程序使用矩阵快速幂运算方式来提高运行速度,计算到第1亿个数都没有问题。

程序中使用了rvelthuis的Delphi BigNumbers,可到下面的地址下载: 

GitHub - rvelthuis/DelphiBigNumbers: BigInteger and BigDecimal for Delphi

unit uMain;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
  System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
  Vcl.StdCtrls, Vcl.ComCtrls;

type
  TForm1 = class(TForm)
    RichEditResult: TRichEdit;
    ButtonCalc: TButton;
    EditNum: TEdit;
    EditTime: TEdit;
    Label1: TLabel;
    Label2: TLabel;
    procedure ButtonCalcClick(Sender: TObject);
  private
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

uses uMatrix2;

procedure TForm1.ButtonCalcClick(Sender: TObject);
var
  M: TMatrix2;
  Delta: TDateTime;
begin
  EditTime.Text := '';
  RichEditResult.Text  := '';
  Application.ProcessMessages;
  M.Init(1,1,1,0);
  Delta := Now();
  M := M.Pow(StrToInt(EditNum.Text));
  Delta := Now() - Delta;
  EditTime.Text := FormatDateTime('n:s.zzz', Delta);
  RichEditResult.Text := M.Value[1,2].ToString;
end;

end.
object Form1: TForm1
  Left = 0
  Top = 0
  Caption = 'Form1'
  ClientHeight = 582
  ClientWidth = 960
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  Position = poScreenCenter
  DesignSize = (
    960
    582)
  PixelsPerInch = 96
  TextHeight = 13
  object Label1: TLabel
    Left = 362
    Top = 554
    Width = 48
    Height = 13
    Caption = #35745#31639#32791#26102
  end
  object Label2: TLabel
    Left = 720
    Top = 555
    Width = 43
    Height = 13
    Caption = #31532'N'#20010#25968
  end
  object RichEditResult: TRichEdit
    Left = 8
    Top = 8
    Width = 944
    Height = 532
    Anchors = [akLeft, akTop, akRight, akBottom]
    Font.Charset = GB2312_CHARSET
    Font.Color = clWindowText
    Font.Height = -11
    Font.Name = 'Tahoma'
    Font.Style = []
    Lines.Strings = (
      '')
    ParentFont = False
    ScrollBars = ssVertical
    TabOrder = 0
    Zoom = 100
  end
  object ButtonCalc: TButton
    Left = 877
    Top = 549
    Width = 75
    Height = 25
    Anchors = [akRight, akBottom]
    Caption = 'calc'
    TabOrder = 1
    OnClick = ButtonCalcClick
  end
  object EditNum: TEdit
    Left = 768
    Top = 551
    Width = 89
    Height = 21
    Anchors = [akRight, akBottom]
    TabOrder = 2
    Text = '10'
  end
  object EditTime: TEdit
    Left = 416
    Top = 551
    Width = 89
    Height = 21
    TabOrder = 3
  end
end
unit uMatrix2;

interface

uses Vcl.Dialogs, System.SysUtils, Velthuis.BigIntegers;

type
  BigInt =  BigInteger;

  TMatrix2 = record
    Value: array[1..2, 1..2] of BigInt;
  public
    class operator Multiply(const A, B: TMatrix2): TMatrix2;
    class operator Add(const A, B: TMatrix2): TMatrix2;
    class operator Equal(const A, B: TMatrix2): Boolean;
    class operator Implicit(const aValue: UInt64): TMatrix2;
    function Pow(N: UInt64): TMatrix2;
    function ToString: String;
    procedure Init(const A, B, C, D: BigInt);
  end;

implementation

function TMatrix2.Pow(N: UInt64): TMatrix2;
var
  Base: TMatrix2;
begin
  if N = 0 then
    Result := 1
  else if N = 1 then
    Result := Self
  else
  begin
    Result := 1;
    Base   := Self;
    while N > 0 do
    begin
      if (N and 1) > 0 then
        Result := Result * Base;
      Base := Base * Base;
      N := (N shr 1);
    end;
  end;
end;

class operator TMatrix2.Implicit(const aValue: UInt64): TMatrix2;
begin
  Result.Value[1, 1] := aValue;
  Result.Value[1, 2] := 0;
  Result.Value[2, 1] := 0;
  Result.Value[2, 2] := aValue;
end;

class operator TMatrix2.Equal(const A, B: TMatrix2): Boolean;
var
  I, J: Integer;
begin
  Result := True;
  for I := 1 to 2 do
  begin
    for J := 1 to 2 do
    begin
      if A.Value[I, J] <> B.Value[I, J] then
      begin
        Result := False;
        Exit;
      end;
    end;
  end;
end;

class operator TMatrix2.Add(const A, B: TMatrix2): TMatrix2;
var
  I, J: Integer;
begin
  for I := 1 to 2 do
  begin
    for J := 1 to 2 do
    begin
      Result.Value[I, J] := A.Value[I, J] + B.Value[I, J];
    end;
  end;
end;

class operator TMatrix2.Multiply(const A, B: TMatrix2): TMatrix2;
var
  I, J: Integer;
begin
  for I := 1 to 2 do
  begin
    for J := 1 to 2 do
    begin
      Result.Value[I, J] := A.Value[I, 1] * B.Value[1, J] +
                            A.Value[I, 2] * B.Value[2, J]
    end;
  end;
end;

function TMatrix2.ToString: String;
begin
  Result := Format('[[%s, %s], [%s, %s]]',
            [Value[1, 1].ToString, Value[1, 2].ToString,
             Value[2, 1].ToString, Value[2, 2].ToString]);
end;

procedure TMatrix2.Init(const A, B, C, D: BigInt);
begin
  Value[1, 1] := A;
  Value[1, 2] := B;
  Value[2, 1] := C;
  Value[2, 2] := D;
end;

end.

标签:begin,end,Delphi,Value,TMatrix2,斐波,Fibonacci,const,Result
来源: https://blog.csdn.net/BlueStorm/article/details/123109754

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有