您似乎在使用字符串而不是数组。在这种情况下你需要这个函数:
function RemoveAdjacentDuplicates(const X: string): string;
var
i, j: Integer;
begin
SetLength(Result, Length(X));
j := 0;
for i := 1 to Length(Result) do
if (i=1) or (X[i]<>X[i-1]) then
begin
inc(j);
Result[j] := X[i];
end;
SetLength(Result, j);
end;
让我们解决这个问题。
首先我分配结果变量。这很可能是过度分配。我们知道结果不能大于输入。
我们使用两个索引局部变量,名称相当弱的i 和j。我们可以给它们起描述性的名称,但对于这么短的函数,人们可能会认为没有必要。如果您愿意,请随时提出其他名称。例如,您可以选择idxIn 和idxOut。
一个变量索引输入,另一个索引输出。输入索引用于简单的 for 循环。每次我们找到一个唯一的项目时,输出索引都会增加。
if 条件测试输入索引是否引用了与前一个不同的字符。第一个元素没有前一个元素,所以我们总是包含它。
一旦循环完成,我们就知道输出有多长并且可以执行最终分配。
为数组调整它很简单。您只需要考虑使用从零开始的索引的数组。为了好玩,这里有一个通用的数组版本:
type
TMyArrayHelper = class
class function RemoveAdjacentDuplicates<T>(const X: array of T): TArray<T>;
static;
end;
class function TMyArrayHelper.RemoveAdjacentDuplicates<T>
(const X: array of T): TArray<T>;
var
i, j: Integer;
Comparer: IEqualityComparer<T>;
begin
Comparer := TEqualityComparer<T>.Default;
SetLength(Result, Length(X));
j := 0;
for i := 0 to high(Result) do
if (i=0) or not Comparer.Equals(X[i], X[i-1]) then
begin
Result[j] := X[i];
inc(j);
end;
SetLength(Result, j);
end;
注意inc(j) 的位置略有不同。这是切换到从零开始的索引所必需的。
一个稍微复杂一点的测试更少的替代方案是:
class function TMyArrayHelper.RemoveAdjacentDuplicates<T>
(const X: array of T): TArray<T>;
var
i, j, len: Integer;
Comparer: IEqualityComparer<T>;
begin
Comparer := TEqualityComparer<T>.Default;
len := Length(X);
SetLength(Result, len);
if len=0 then
exit;
Result[0] := X[0];
j := 1;
for i := 1 to len-1 do
if not Comparer.Equals(X[i], X[i-1]) then
begin
Result[j] := X[i];
inc(j);
end;
SetLength(Result, j);
end;