其他分享
首页 > 其他分享> > Delphi 生成不重复随机数类

Delphi 生成不重复随机数类

作者:互联网

原文链接:http://www.cnblogs.com/kernelj/archive/2010/01/27/1657296.html

本类可用来产生从MinNumber到MaxNumber之间的随机数,只要设定Unique,每个数字就只使用一次。此外还可以检查数字是否使用过。一个动态的Tbit数组用来保证数字只会返回一次,并看是否所有的数字都使用过。

 

unit REngine;
interface

uses Windows,Classes;

type
     TRandomEngine = class(TObject)
     private
        FSelected : TBits;
        FArrSize,FNumbersUsed : longint;
        FMinNumber,FMaxNumber : longint;
        FUnique : boolean;
        procedure SizeSelArray;
        procedure SetFMinNumber(NewValue : longint);
        procedure SetFMaxNumber(NewValue : longint);
        function GetFNumbersFree : longint;
     public
        constructor Create;
        destructor Destroy; override;
        procedure Reset;
        function GetRandom : longint;
        function IsUsed(Index : longint) : boolean;
        property MinNumber : longint read FMinNumber write SetFMinNumber;
        property MaxNumber : longint read FMinNumber write SetFMaxNumber;
        property Unique : boolean read FUnique write FUnique;
        property NumbersUsed : longint read FNumbersUsed;
        property NumbersTotal : longint read FArrSize;
        property NumbersFree : longint read GetFNumbersFree;
     end;


// ===================================
// 创建和释放对象
// ===================================

constructor TRandomEngine.Create;
begin
  FSelected := TBits.Create;
  FNumbersUsed := 0;
  FMinNumber := 0;
  FMaxNumber := 0;
  FArrSize := 0;
  FUnique := false;
  Randomize;
end;

destructor TRandomEngine.Destroy;
begin
  inherited Destroy;
  FSelected.Free;
end;

// ===========================
// Get/Set方法
// ===========================

procedure TRandomEngine.SetFMinNumber(NewValue : longint);
begin
  if (NewValue <> FMinNumber) then
  begin
     FMinNumber := NewValue;
     if FMinNumber > FMaxNumber then FMaxNumber := FMinNumber;
     SizeSelArray;
  end;
end;

procedure TRandomEngine.SetFMaxNumber(NewValue : longint);
begin
  if (NewValue <> FMaxNumber) then
  begin
     FMaxNumber := NewValue;
     if FMaxNumber < FMinNumber then FMinNumber := FMaxNumber;
     SizeSelArray;
  end;
end;

function TRandomEngine.GetFNumbersFree : longint;
begin
  Result := FArrSize - FNumbersUsed;
end;

// =======================================
// 调整布尔数组(FSelected)的大小
// =======================================

procedure TRandomEngine.SizeSelArray;
var i : longint;
begin
  FArrSize := FMaxNumber - FMinNumber + 1;

  if FArrSize > 0 then
  begin
    FSelected.Size := FArrSize;
    for i := 0 to FArrSize - 1 do FSelected[i] := false;
  end;

  FNumbersUsed := 0;
end;

// =======================================
// 重置可用,已用,未用数字。
// 为IsUsed()重置Fselected数组,
// 使之为false。
// =======================================

procedure TRandomEngine.Reset;
begin
  SizeSelArray;
end;

// ===================================================
// 如果已设定Unique,数字已使用,
// 则返回true/false。
// ===================================================

function TRandomEngine.IsUsed(Index : longint) : boolean;
var Retvar : boolean;
begin
  if (Index < FMinNumber) or (Index > FMaxNumber) then
      Retvar := false
  else
      RetVar := FSelected[Index - FMinNumber];

  Result := RetVar;
end;

// ===================================================
// 根据最小和最大值返回随机数。如果
// 已设定Unique,则根据Fselected数
// 组生成(即保证数字未用过)。
// ===================================================

function TRandomEngine.GetRandom : longint;

var V : longint;
    NumSelected : boolean;
begin
  if FUnique and (FNumbersUsed = FArrSize) then
     V := 0
  else
  begin
     repeat
        V := Random(FMaxNumber - FMinNumber + 1) + FMinNumber;
        if not FUnique then
           NumSelected := true
        else begin
           if FSelected[V - FMinNumber] then
              NumSelected := false
           else begin
              NumSelected := true;
              FSelected[V - FMinNumber] := true;
              inc(FNumbersUsed);
           end;
        end;
     until NumSelected;
  end;

  Result := V;
end;

end.

 

 

转载于:https://www.cnblogs.com/kernelj/archive/2010/01/27/1657296.html

标签:begin,end,重复,Delphi,TRandomEngine,longint,随机数,FMinNumber,FMaxNumber
来源: https://blog.csdn.net/weixin_30724853/article/details/96618401