帕斯卡尔:如何比较大数字

时间:2017-10-21 09:10:09

标签: string performance comparison pascal long-integer

我有包含整数的字符串,这可能比maxInt更加缓慢,我需要比较它们,所以最好的方法是做什么。 这是我的代码示例:

   x := 1;
   Reset(File1);
   While Not eof(File1) do
   Begin
      Read(File1, num[i]);
      Inc(i)
   End;
   z := i;
   w := z + 1;
   j := z + 1;
   While Not eof(File1) do
   Begin
      Read(File1, num[j]);
      Inc(j)
   End;
   y := j;
   If
   If j > i Then a := 1 Else If j = i Then
   Begin
      While z <> x do
      Begin
         If  Ord(num[j]) > Ord(num[i]) Then a := 1 Else If Ord(num[j]) < Ord(num[i]) Then a := 0;
         Dec(j);
         Dec(i)
      End;
   End Else a := 0;
   If a = 1 Then
   Begin
      x := z+1;
      z := y
   End;

1 个答案:

答案 0 :(得分:3)

如果您要做的唯一事情是比较包含可能大于编译器具有内置例程的数字的字符串,您可以比较字符串本身。

首先比较长度,如果相同,从左到右比较字符将是一个很好的策略。

<强> NB。如果您的字符串包含尾随或前导空格,前导零,请在比较前删除它们。

下面是一个使用stringlist按升序对值(作为字符串)进行排序的示例(应该在Delphi和freepascal中工作):

program ProjTestBigIntSort;

{$APPTYPE CONSOLE}

uses
  Classes;

type
  TMyStringList = class(TStringList)
  protected
    function CompareStrings(const S1, S2: string): Integer; override;
  end;

function TMyStringList.CompareStrings(const S1, S2: string): Integer;
var
  i : Integer;
begin
  // Trimming leading/trailing spaces and leading zeroes might be needed first
  Result := 0;
  // Compare length, shortest sorts first
  if (Length(S1) > Length(S2)) then begin
    Result := 1;
    Exit;
  end;
  if (Length(S1) < Length(S2)) then begin
    Result := -1;
    Exit;
  end;
  // Same length, compare digits from left to right:
  i := 1;
  while (i <= Length(S1)) do begin
    if (Ord(S1[i]) < Ord(S2[i])) then begin
      Result := -1;
      Exit;
    end
    else
    if (Ord(S1[i]) > Ord(S2[i])) then begin
      Result := 1;
      Exit;
    end;
    Inc(i);
  end;
end;

procedure Test;
var
  SL: TMyStringList;
  s: String;
begin
  SL:= TMyStringList.Create;
  try
    SL.Add('1');
    SL.Add('99999999999999999999999999999');
    SL.Add('88888888888888888888888888888');
    SL.Add('99999999999999999999');
    SL.Sort;
    for s in SL do WriteLn(s);
  finally
    SL.Free;
  end;
end;

begin
  Test;
  ReadLn;
end.  

输出:

1
99999999999999999999
88888888888888888888888888888
99999999999999999999999999999

<强>更新

如果数字可能是负数,则可以通过此比较测试来解决:

function TMyStringList.CompareStrings(const S1, S2: string): Integer;
var
  i : Integer;
  cmpNegative : Boolean;
const
  cNeg : array[boolean] of Integer = (1,-1);
begin
  // Trimming leading/trailing spaces and leading zeroes might be needed first
  Result := 0;
  cmpNegative := false;
  // Test for negative numbers
  if (S1[1] = '-') then begin
    if (S2[1] <> '-') then begin
      Result := -1;
      Exit;
    end;
    // Both numbers negative, reverse comparison
    cmpNegative := true;
  end
  else
  if (S2[1] = '-') then begin
    Result := 1;
    Exit;
  end;
  // Compare length, shortest sorts first
  if (Length(S1) > Length(S2)) then begin
    Result := 1*cNeg[cmpNegative];
    Exit;
  end;
  if (Length(S1) < Length(S2)) then begin
    Result := -1*cNeg[cmpNegative];
    Exit;
  end;
  i := 1;
  while (i <= Length(S1)) do begin
    if (Ord(S1[i]) < Ord(S2[i])) then begin
      Result := -1*cNeg[cmpNegative];
      Exit;
    end
    else
    if (Ord(S1[i]) > Ord(S2[i])) then begin
      Result := 1*cNeg[cmpNegative];
      Exit;
    end;
    Inc(i);
  end;
end;

如果您需要对值进行算术运算,请考虑使用大整数包。见Delphi fast plus big integer?