【问题标题】:Remove same element array in delphi在delphi中删除相同的元素数组
【发布时间】:2014-04-10 06:32:20
【问题描述】:

我正在尝试在 delphi 中删除相同的数组元素。 例如:
R[1] := 33332111111111111111111111323333333334378777433333344333333333277

我想让它变成 32132343787434327. 并保存在新数组中。
能给个思路吗?

我已经尝试将每个 R[1] 元素设置为数组。并尝试了一些代码。

  for i:=1 to length(NR) do
  begin
    found:=false;
    for k:=i+1 to length(NR) do
    begin
        if (NR[i]=NR[k]) then
        begin
          found:=true;
        end;
    end;
    if (not found) then
    begin
      Memo1.Lines.Add(NR[i]);
    end;
  end;

但结果是 184327。
你们能帮帮我吗?多谢。我非常渴望这样做。

【问题讨论】:

    标签: delphi


    【解决方案1】:

    您似乎在使用字符串而不是数组。在这种情况下你需要这个函数:

    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;
    

    让我们解决这个问题。

    首先我分配结果变量。这很可能是过度分配。我们知道结果不能大于输入。

    我们使用两个索引局部变量,名称相当弱的ij。我们可以给它们起描述性的名称,但对于这么短的函数,人们可能会认为没有必要。如果您愿意,请随时提出其他名称。例如,您可以选择idxInidxOut

    一个变量索引输入,另一个索引输出。输入索引用于简单的 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;
    

    【讨论】:

    • 我会将(i=0) 比较移出循环。第一个元素可以盲目添加,只有i &gt; 0 的元素需要比较(对于每个后继者都是如此)。如果我们添加第一个并让循环从索引 1 开始,我们必须只检查一次,而不是 High(Result) 次。
    • @JensG 谢谢。我同意这种方式效率更高。但更容易阅读我的方式。鉴于提问者的经验,这就是我的目标。但我确实同意你的观点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-01-31
    • 1970-01-01
    • 2017-04-27
    • 2019-07-06
    • 1970-01-01
    • 2023-03-17
    • 1970-01-01
    相关资源
    最近更新 更多