在Delphi中生成三个随机字符
您好,我正在尝试使用Delphi中的函数生成三个随机字符,代码如下:在Delphi中生成三个随机字符,delphi,Delphi,您好,我正在尝试使用Delphi中的函数生成三个随机字符,代码如下: function generate(cantidad: integer): string; const letras_mi = 'abcdefghijklmnopqrstuvwxyz'; const letras_ma = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; const numeros = '0123456789'; var finalr: string; begin finalr
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;
问题是,像20142这样的东西让我回过神来,而我实际上在等待3个字符的常量随机变量。您将
随机的结果添加到您的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;
让我们看看编译器所看到的代码在做什么:
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]
您的代码正在将整数索引值转换为字符串。请注意,对常量的唯一引用是获取它们的长度。返回索引而不是字符
您可以通过使用生成的整数索引来引用字符串常量中的元素来修复代码。梅森和肯演示了如何做到这一点
就我个人而言,我会去掉常数,然后写
Chr(ord('a') + Random(26))
及
及
这些字符的序数值早在允许这种代码的时候就设计好了 更快的方法是避免一次又一次地重新分配内存
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;
有时,使用局部变量来避免对var参数结果进行一些额外的UniqueString
调用,甚至会稍微快一点
但是,应该针对特定的编译器版本和选项进行计时或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;
基于Ord的方法在这里也比从数组/字符串中选取字符要好,但这是独立的问题。另外,在Delphi 2009或更高版本中使用Chr
函数时,我会非常小心,因为它只能在#0..#127个值上工作。明确声明的类型转换,如AnsiChar(i)
和WideChar(i)
可能是更稳定的替代,因为有一天你需要7位子范围之外的字母,比如eña和其他欧洲特有的字母。这将生成看起来像单词的随机字符串
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) 非常优雅的解决方案:-)删除常量的一个优点是EXE大小(虽然不是很大),但如果要在更大的范围内执行此操作,假设这些常量在50个不同的位置使用,那么在编译时所有这些常量都将被连续复制-并且所有这些字符都将相加。这并不是说它有太大的区别,可能是1kb,但仍然如此。@Jerrydoge我就是这样做的,因为我来自80年代,这就是我当时学习它的方式。对我来说,理解和检查似乎更简单。这些常量中很容易漏掉一个字母。这些字母都是用字符集编码的。我不喜欢重复。我见过有人创建了一个可能包含1000个字符的字符串常量,并在许多不同的地方使用该常量。没有意识到的是,编译会将该常量复制到引用该常量的字符串文本的数量。例如,一个1000字符的常数被使用50次,总共会产生50000个字符。谢谢你的帮助,但我有一个问题,因为我想生成从1到3的随机数,我有这个:随机(4-1)+1,我想知道这是否可以,因为如果我在随机数组中使用时做得不好,会给我带来错误部分收缩与我正在编译调试信息有关,所以我改为Release
,但仍然确认正在进行一些优化,我的理论是错误的。你应该对传入的参数cantidad做些什么吗?@MarcusAdams:cantidad是西班牙语中“数量”的意思,所以我假设我们这里有一个更大函数的片段,其中该参数充当for循环的端点。好吧,更快似乎不是问题。但是更快、更干净、更简单的方法是使用+
操作符编写所有代码。@DavidHeffernan,这使得它在处理Unicode之前的Delphi(libs,遗留项目)的代码时出人意料地含糊不清。你生活在一个拉丁字母的国度,没有被这些问题所困扰。但是,我不确定除a..Z之外的ella、eña和其他欧洲字母在win1250和utf-16中是否具有完全相同的Ord然后将这个表达添加到您的答案中,供未来的新手读者尝试并集中精力回答所提出的问题。我们在谈论拉丁字母!A..Z,A..Z和0..9。如果您想讨论其他信件,请尝试另一个问题。;-)我从一开始就发表了这样的评论。然而,脆弱的做法并不是那些已经被打破的做法,而是那些为未来计划扩展埋下地雷的做法。我希望人们提前得到警告。谢谢你提供的答案。请编辑您的答案,包括对代码的解释,好吗?这将有助于未来的读者更好地理解正在发生的事情,尤其是那些对该语言不熟悉并努力理解这些概念的社区成员。
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;
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;
const
Alphabetdown = 'abcdefghijklmnopqrstuvwxyz' ;
procedure TForm1.Button1Click(Sender: TObject);
var
sGeneratedAccNo : string ;
begin
sGeneratedAccNo := sGeneratedAccNo + Alphabetdown[Random(Length(Alphabetdown) + 1)] ;
showMessage(sGeneratedAccNo) ;
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;
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;