2017-10-21 267 views
0

J'ai des chaînes qui contiennent des entiers, qui peuvent être plus gros que maxInt, et j'ai besoin de les comparer, alors quelle serait la meilleure façon de faire cela. ici est l'exemple de mon code:Pascal: comment comparer les grands nombres

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; 

Répondre

3

Si la seule chose que vous voulez faire est de comparer les chaînes qui contient des nombres peut-être plus grand que le compilateur a intégré dans les routines pour, vous pouvez comparer les chaînes elles-mêmes.

En comparant d'abord la longueur et si c'est la même chose, comparer les caractères de gauche à droite serait une bonne stratégie.

NB. Si vos chaînes contiennent des espaces de début ou de fin, des zéros en tête, supprimez-les avant de les comparer.

Voici un exemple en utilisant un stringlist pour trier les valeurs (sous forme de chaînes) dans l'ordre croissant (Devrait fonctionner dans Delphi et 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. 

Sortie:

1 
99999999999999999999 
88888888888888888888888888888 
99999999999999999999999999999 

Mise à jour:

Si les nombres peuvent être négatifs, cela pourrait être corrigé par ce compa test Rison:

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; 

Si vous devez effectuer des opérations arithmétiques sur les valeurs, pensez à utiliser un gros paquet entier. Voir Delphi fast plus big integer?

+1

Malgré mon vote positif, je pensais simplement aux nombres négatifs et à la manipulation des signes négatifs. –

+0

@LURD déjà lié à une liste. Je voudrais recommander mon [BigNumbers] (https://github.com/rvelthuis/BigNumbers): Docs [commencer ici] (http://www.rvelthuis.de/programs/bigintegers.html). –

+0

@MarkSetchell, merci, a également ajouté un test pour les nombres négatifs. –