13

您好我正在尝试使用 Delphi 中的函数生成三个随机字符,代码是这样的:

function generate(cantidad: integer): string;
const
  letras_mi = 'abcdefghijklmnopqrstuvwxyz';
const
  letras_ma = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
const
  numeros = '0123456789';
var
  finalr: string;
begin

  finalr := '';

  finalr := finalr + IntToStr(Random(Length(letras_mi)) + 1);
  finalr := finalr + IntToStr(Random(Length(letras_ma)) + 1);
  finalr := finalr + IntToStr(Random(Length(numeros)) + 1);

  Result := finalr;

end;

问题是,当我实际上在等待 3 个字符的常量随机变量时,我回来了 20142 之类的东西。

4

8 回答 8

24

您的代码正在将整数索引值转换为字符串。请注意,您对常量的唯一引用是取它们的长度。您返回索引而不是字符。

您可以通过使用您生成的整数索引来引用字符串常量中的元素来修复您的代码。梅森和肯展示了如何做到这一点。

就我个人而言,我会取消常量并写

Chr(ord('a') + Random(26))

Chr(ord('A') + Random(26))

Chr(ord('0') + Random(10))

这些字符的序数值是在允许此类代码时设计的。

于 2013-11-09T22:45:37.980 回答
13

您将结果添加Random到您的finalr中,而不是常量中的随机字母。

尝试这样的事情 - 它使用返回Random作为字符串常量字符的索引:

function generate(cantidad: integer): string;
const
  letras_mi = 'abcdefghijklmnopqrstuvwxyz';
  letras_ma = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
  numeros = '0123456789';
begin
  Result := '';
  Result := Result + letras_mi[Random(Length(letras_mi)) + 1];
  Result := Result + letras_ma[Random(Length(letras_ma)) + 1];
  Result := Result + numeros[Random(Length(numeros)) + 1];
end;
于 2013-11-09T22:29:23.900 回答
10

让我们看看你的代码在做什么,就像编译器看到的那样:

IntToStr(Random(Length(letras_mi)) + 1)

Call IntToStr on the result of:
  Call Random on the result of:
    Add
      Length(letras_mi)
      1

IntToStr 接受一个数字(例如5)并将其转换为字符串(例如'5')。您想要做的是使用随机值来索引到您的数组,如下所示:

letras_mi[Random(Length(letras_mi)) + 1]
于 2013-11-09T22:31:43.830 回答
1
function RandomString(const ALength: Integer): String;
var
  i: Integer;
  LCharType: Integer;
begin
  Result := '';
  for i := 1 to ALength do
  begin
    LCharType := Random(3);
    case LCharType of
      0: Result := Result + Chr(ord('a') + Random(26));
      1: Result := Result + Chr(ord('A') + Random(26));
      2: Result := Result + Chr(ord('0') + Random(10));
    end;
  end;
end;
于 2017-07-21T11:05:45.917 回答
1

这将生成看起来像单词的随机字符串。

function GenerateRandomWord(CONST Len: Integer=16; StartWithVowel: Boolean= FALSE): string;
CONST
   sVowels: string= 'AEIOUY';
   sConson: string= 'BCDFGHJKLMNPQRSTVWXZ';    
VAR
   i: Integer;
   B: Boolean;
begin
  B:= StartWithVowel;
  SetLength(Result, Len);
  for i:= 1 to len DO
   begin
    if B
    then Result[i]:= sVowels[Random(Length(sVowels)) + 1]
    else Result[i]:= sConson[Random(Length(sConson)) + 1];
    B:= NOT B;
   end;
end;

所以,像这样使用它: GenerateRandomWord(3);

于 2016-03-12T07:51:38.883 回答
1
const
Alphabetdown = 'abcdefghijklmnopqrstuvwxyz' ;
procedure TForm1.Button1Click(Sender: TObject);
var
   sGeneratedAccNo : string ;

begin
    sGeneratedAccNo := sGeneratedAccNo + Alphabetdown[Random(Length(Alphabetdown) + 1)] ;
    showMessage(sGeneratedAccNo) ;
于 2016-09-20T20:30:14.000 回答
0

更快的方法是避免一次又一次地重新分配内存。

function generate(cantidad: integer): string;
const
  letras_mi = 'abcdefghijklmnopqrstuvwxyz';
  numeros = '0123456789';
begin
  SetLength(Result, 3); // only alloc memory once

  Result[1] := letras_mi[Random(Length(letras_mi)) + 1];
  Result[2] := UpCase(letras_mi[Random(Length(letras_mi)) + 1]);
  Result[3] := numeros[Random(Length(numeros)) + 1];
end;

有时甚至会稍微快一点,使用局部变量来避免UniqueString对 var-parameter 的额外调用Result

但是,应该针对特定的编译器版本和选项进行计时或 CPU 级别的代码检查,以查看这实际上会产生什么差异(如果有的话)。

function generate(cantidad: integer): string;
const
  letras_mi = 'abcdefghijklmnopqrstuvwxyz';
  numeros = '0123456789';
var local: string;
begin
  SetLength(local, 3); // only alloc memory once

  local[1] := letras_mi[Random(Length(letras_mi)) + 1];
  local[2] := UpCase(letras_mi[Random(Length(letras_mi)) + 1]);
  local[3] := numeros[Random(Length(numeros)) + 1];

  Result := local;
end;

PS。基于 Ord 的方法在这里也比从数组/字符串中选择一个字符更好,但这是独立的问题。此外,我会谨慎使用ChrDelphi 2009 或更高版本的函数,它只能在 #0..#127 值上统一工作。明确声明类型转换,例如AnsiChar(i)并且WideChar(i)可能是更稳定的替代品,因为有一天您需要 7 位子范围之外的字母,例如 eña 和其他特定于欧洲的字母。

于 2013-11-11T06:58:22.483 回答
0
  function generate(cantidad: integer): string;
  const
    letras_mi = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
    var i:integer;
  begin
    Result := '';
    for I := 1 to cantidad do
      Result := Result + letras_mi[Random(Length(letras_mi)) + 1];
  end;

  function generateNum(cantidad: integer): string;
  const
    letras_mi = '0123456789';
    var i:integer;
  begin
    Result := '';
    for I := 1 to cantidad do
      Result :=  Result + letras_mi[Random(Length(letras_mi)) + 1];
  end;
于 2020-12-11T18:43:23.320 回答