在Delphi中调整动态数组大小的最佳方法是什么?
作为一名Delphi新手,我编写了一个简单的函数,该函数给定一个字符串和一个字符,返回该字符在字符串中出现的索引 但是,我不确定我的实现是否最优(因为我一直在调整动态数组的大小)。有没有更好的方法来实现这一点:在Delphi中调整动态数组大小的最佳方法是什么?,delphi,Delphi,作为一名Delphi新手,我编写了一个简单的函数,该函数给定一个字符串和一个字符,返回该字符在字符串中出现的索引 但是,我不确定我的实现是否最优(因为我一直在调整动态数组的大小)。有没有更好的方法来实现这一点: type Indexes = array of Integer; function GetCharacterIndexesInString(inputstring:string; c:char) : Indexes; var s : char; count : intege
type Indexes = array of Integer;
function GetCharacterIndexesInString(inputstring:string; c:char) : Indexes;
var
s : char;
count : integer;
position: integer;
begin
count := 0;
position := 0;
SetLength(result, 0);
for s in inputstring do
begin
if s = c then
begin
count := count+1;
SetLength(result, count);
result[count-1] := position;
end;
position := position+1;
end;
end;
当最终大小未知时,有一种经典的渐进快速调整阵列大小的算法。我们不是将其大小调整1,而是在空间不足时将其大小加倍。完成后,设置数组的实际大小 代码如下:
type Indexes = array of Integer;
function GetCharacterIndexesInString(inputstring:string; c:char) : Indexes;
var
s : char;
count : integer;
position: integer;
capacity: Integer; //TList uses same method internally :)
const InitCapacity: Integer = 16;
begin
count := 0;
position := 0;
capacity := InitCapacity;
SetLength(result, InitCapacity);
for s in inputstring do
begin
if s = c then
begin
inc(count); //adds 1 to count, delphi analog of ++
if count > capacity then begin
capacity := capacity * 2;
SetLength(result, capacity);
end;
result[count-1] := position;
end;
inc(position);
end;
SetLength(result, count);
end;
UPD。根据David Heffernan的建议修改了代码,现在它以16的长度开始,这应该会加快一点速度。此外,还可以“调优”InitCapacity,代码在这里使用任何正数。例如,您可以收集统计信息:结果数组的平均长度,并将InitCapacity设置为略大于此平均长度。可能取决于您提供的典型输入。我怀疑一种算法对于所有可能的输入都是最优的。另一种方法是使用TList而不是动态数组。在那里,它已经实现了,我们不关心长度,而不是'result[count-1]:=position'write'result.Add(position)'。但有一个警告:这个函数的结果必须在某个时候释放。这在早期分配中可能是浪费的,因为会有一个最小的块大小。我可能从16或32开始,或者更好。首先读入固定长度数组。如果它已满,请切换到动态数组。如果没有,您可以通过一个堆分配完成整个任务。FWIW,有人抱怨
TList
,当必须调整数组大小时,它确实会使数组大小加倍。人们更喜欢TList
(非通用)的功能,即只添加当前大小的一半。他们发现加倍太浪费了。很可能,TList
实际上更浪费,执行更多的分配,并创建无法重复使用的块。例如,您可能会得到大小为256、384和512的块,而不仅仅是256和512的块。如果这1.5倍的数据块可以重复使用,那么TList
方法的浪费就更少了。大多数人在讨论这些问题时,对内存分配在各个级别(系统和库)的工作原理了解不够,无法构造有效的参数。@DavidHeffernan I更新了答案,从数组大小16开始。