前言

经常需要用到 随机数 和 随机长度的字符串,我们接下来看下 在delphi 里如何使用,原来我一直都用错了 Randomize,这个方法只需要程序运行时,写一次就行了,不需要导出写,一个程序只需要一句;

随机数

procedure TForm3.Button1Click(Sender: TObject);
begin
  Memo1.Lines.Clear;
  for var I := 0 to 100 do
  begin
    //Randomize; 根本就不需要这个,就能实现随机数
    Memo1.Lines.Add(Random(10).ToString);
  end;
end;

image

那还要 Randomize 干什么???

我们去官方的看下:

System.Random - RAD Studio API 文档 (embarcadero.com)

System.Math.RandomRange - RAD Studio API 文档 (embarcadero.com)

System.Randomize - RAD Studio API 文档 (embarcadero.com)

官方的解释绝了,我直接截图吧

image

image

image

试验

对比下 循环内 和 循环外 是否有差别:

procedure TForm3.Button1Click(Sender: TObject);
begin
  Memo1.Lines.Clear;
  Randomize; //只在循环外用一次
  for var I := 0 to 100 do
  begin
    Memo1.Lines.Add(Random(10).ToString);
  end;
end;

procedure TForm3.Button2Click(Sender: TObject);
begin
  Memo2.Lines.Clear;
  for var I := 0 to 100 do
  begin
    Randomize; //在循环内使用,每次循环都用一次
    Memo2.Lines.Add(Random(10).ToString);
  end;
end;

image

可见在循环内使用,会导致 更多的重复,所以不要在循环内使用;

看下指定范围随机

uses System.Math; //范围随机的话,需要引入这个

procedure TForm3.Button1Click(Sender: TObject);
begin
  Memo1.Lines.Clear;
  Randomize; //只在循环外用一次
  for var I := 0 to 100 do
  begin
    Memo1.Lines.Add(RandomRange(5, 8).ToString);
  end;
end;

procedure TForm3.Button2Click(Sender: TObject);
begin
  Memo2.Lines.Clear;
  for var I := 0 to 100 do
  begin
    Randomize; //在循环内使用,每次循环都用一次
    Memo2.Lines.Add(RandomRange(5, 8).ToString);
  end;
end;

image

可见范围随机 是 from =< x < to,比如 RandomRange(5, 8) 就是 5、6、7 不包含8;

随机字符串

直接使用官方现成的函数,引用 System.Hash 单元,推荐使用官方的,简单方便

procedure TForm3.Button2Click(Sender: TObject);
begin
  Memo2.Lines.Clear;
  for var I := 0 to 100 do
  begin
    Randomize; //在循环内使用,每次循环都用一次
    Memo2.Lines.Add(RandomRange(5, 8).ToString);
  end;
end;

image

官方的这个 包含了 符号,如_*等等,我们看下 官方的实现:

class function THash.GetRandomString(const ALen: Integer): string;
const
  ValidChars: string = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+-/*_';
var
  I, L: Integer;
  PC, PV: PChar;
begin
  L := Length(ValidChars);
  SetLength(Result, ALen);
  PC := Pointer(Result);
  PV := Pointer(ValidChars);
  for I := 1 to ALen do
  begin
    PC^ := PV[Random(L)];
    Inc(PC);
  end;
end;

若只要字母和数字怎么办呢;

方法二(自己写的):

function suiJiString(ALen: Integer): string;
const
  chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
begin
  Randomize; 
  SetLength(Result, ALen);
  for var i := 1 to ALen do
  begin
    Result[i] := chars[Random(62) + 1];
  end;
end;

从代码上看我这个效率更高,对比下 看下

procedure TForm3.Button5Click(Sender: TObject);
begin
  var start := GetTickCount;
  Button3Click(Sender);
  Memo2.Lines.Add('官方的耗时:' + (GetTickCount - start).ToString);
  start := GetTickCount;
  Button4Click(Sender);
  Memo2.Lines.Add('我的耗时:' + (GetTickCount - start).ToString);
end;

image

posted on 2017-05-27 10:19  del88  阅读(1176)  评论(0)    收藏  举报