13

こんにちは、Delphi の関数を使用して 3 つのランダムな文字を生成しようとしています。コードは次のとおりです。

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文字列定数文字へのインデックスとしての return を使用します:

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
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 に答える
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 に答える
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 ベースのアプローチの方が優れていますが、それは独立した問題です。Chrまた、Delphi 2009 以降で関数を使用することには注意が必要です。#0..#127 値でのみ均一に機能します。eña やその他のヨーロッパ固有のもののように、いつの日か 7 ビットのサブレンジ外の文字が必要になるため、明示的に宣言された型キャストのようなものは、より安定した代替品になる可能性がありAnsiChar(i)ます。WideChar(i)

于 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 に答える