【问题标题】:Interpolation Search插值搜索
【发布时间】:2014-07-06 15:26:14
【问题描述】:

如何在 Delphi 中实现泛型插值搜索?我试过从 Wikipedia。但是它返回错误的结果。

function Search(var A: TArray<Integer>; const Index, Count, Item: Integer): Integer;
var
  L, H, M: Integer;
begin
  L := Index;
  H := Count;
  Result := -1;
  while (A[L] <= Item) and (A[H] >= Item)  do
  begin
    M := L + ((Item - A[L]) * (H - L)) div (A[H] - A[L]);
    if A[M] < Item then
      L := M + 1
    else if A[M] > Item then
      H := M - 1
    else
      Exit(M);

    if A[L] = Item then
      Exit(L)
    else
      Exit(-1);
  end;
end;

var
  A: TArray<Integer>;
  I: Integer;
begin
  A := TArray<Integer>.Create(1, 2, 3, 4, 5, 7, 7, 7, 7);
  I := Search(A, 0, High(A), 5); // Returns -1;
  ReadLn;
end.

【问题讨论】:

  • 那么,那段代码有什么问题?
  • 我对 Delphi 中的泛型一无所知,但最好的方法可能是包含一个泛型函数参数——假设 Delphi 允许它——它接受 Item、数组和两个索引,并返回插值索引。这将取代M 的计算。如果不能使用泛型参数,则必须使用函数指针。
  • @Gene 函数不是通用的。它对整数数组进行操作
  • @user3764855 IndexCount 参数是什么意思?它们似乎是不必要的。
  • 使用低(A)和高(A)不行吗?

标签: delphi delphi-xe6


【解决方案1】:

这段代码:

  if A[L] = Item then
      Exit(L)
    else
      Exit(-1);

应该在循环体之外

【讨论】:

  • 如果没有重复则算法返回第一个,如果有重复则返回最后一个。
  • 算法不考虑重复 - 只返回第一个匹配值 - 第一个,第二个,最后一个,任何重复。
【解决方案2】:

完整的工作解决方案。大概可以进一步优化。即使有重复,它也能工作,它只会输出第一个索引,如果你使用LevenshteinDistance之类的东西,它也会与字符串一起工作。

type
    TCompare<T> = reference to function(const L, R: T): Integer;
    TArrayManager<T> = record
        class function InterpolationSearch(var A: TArray<T>; const Index, Count: Integer; const Item: T; const Distance, Compare: TCompare<T>): Integer; static;
    end;

class function TArrayManager<T>.InterpolationSearch(var A: TArray<T>; const Index, Count: Integer; const Item: T; const Distance, Compare: TCompare<T>): Integer;
var
  L, H, M, C: integer;
begin
  L := Index;
  H := Count;
  Result := -1;
  while L <= H do
  begin
    if L = H then
      M := L
    else
    begin
      M := L + (Distance(Item, A[L]) * (H - L)) div Distance(A[H], A[L]);
      if M < L then
        M := L
      else if M > H then
        M := H;
    end;
    C := Compare(A[M], Item);
    if C < 0 then
      L := M + 1
    else
    begin
      H := M - 1;
      if C = 0 then
      Result := M;
    end;
  end;
end;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-10-07
    • 2011-04-09
    • 1970-01-01
    • 2015-11-26
    • 2012-04-24
    • 1970-01-01
    • 2023-02-04
    • 2020-03-16
    相关资源
    最近更新 更多