Avatar billede tango42 Nybegynder
23. september 2003 - 10:28 Der er 5 kommentarer og
2 løsninger

Sortere et array med talværdier

Hej,
Jeg har et array, hvor der er sat 30 tilfældige talværdier ind vha. af en random funktion. Jeg har fået sorteret dem så de står i rækkefølge med de laveste tal først...Problemet er bare, at der er nogle talværdier, som er ens og det er ikke noget jeg ønsker... Er der nogen, som har et forslag til hvad man kan gøre for at undgå problemet med ens værdier?
Avatar billede erikjacobsen Ekspert
23. september 2003 - 10:32 #1
Det kommer an på hvad du vil. Er det tallene fra 1 til 30?
Er der nogen krav på "tilfældighed".

En yderst simpel løsning, som samtidig sorterer dem er:

1) Start med et tilfældigt tal mellem 1 og 10.
2) Vælg nu 29 gange et nyt tilfældigt tal mellem 1 og 10, og
  adder til det foregående.

Vupti: 30 "tilfældige" tal i voksende rækkefølge.
Avatar billede tango42 Nybegynder
23. september 2003 - 10:40 #2
erikjacobsen: Jeg har en random funktion, som f.eks 12 gange vælger et tal mellem 1 og 30... Det tilfældige tal må ikke have en værdi > end de 30, og det vil det med den løsning du foreslår...Men har selv tænkt tanken...
Avatar billede borrisholt Novice
23. september 2003 - 10:42 #3
Function ArrayToString(const a : Array of Integer) : String;
var
  i : Integer;
begin
  Result := '[';
  for i := Low(a) to High(a) do
  begin
    if a[i] < 10 then
      Result := Result + '0' + IntToStr(a[i]) + ','
    else
      Result := Result + IntToStr(a[i]) + ',';
  end;

  Result [Length(Result)] := ']';
end;

procedure QuickSort(var A: array of Integer);
  procedure Sort(iLo, iHi: Integer);
    var
      Lo, Hi, Mid : Integer;
      T: integer;
    begin
      Lo := iLo;
      Hi := iHi;
      Mid := A[(Lo + Hi) div 2];
      repeat
        while A[Lo] < Mid do Inc(Lo);
        while A[Hi] > Mid do Dec(Hi);
        if Lo <= Hi then
        begin
          T := A[Lo];
          A[Lo] := A[Hi];
          A[Hi] := T;
          Inc(Lo);
          Dec(Hi);
        end;
      until Lo > Hi;
      if Hi > iLo then
        Sort(iLo, Hi);
      if Lo < iHi then
        Sort(Lo, iHi);
    end;
begin
  Sort(Low(A), High(A));
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  i, Len : Integer;
  a : Array of integer;
begin
  len := Random(30);
  SetLength(a, Len);
  for i := 0 to Len do
    a[i] := Random(500);

  Memo1.Lines.Add(ArrayToString(A));
  QuickSort(a);
  Memo1.Lines.Add(ArrayToString(A));
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  randomize;
end;


Jens B
Avatar billede tango42 Nybegynder
23. september 2003 - 11:25 #4
Borrisholt: Den sorterer fint med det du foreslår, men der er stadig værdier som er ens....
Avatar billede Slettet bruger
23. september 2003 - 11:33 #5
Måske er der en metode her der virker:

http://www.udvikleren.dk/article.php?aid=140&techid=2
Avatar billede athlon-pascal Juniormester
24. september 2003 - 15:59 #6
Her en lille tilføjelse til Borrisholts eksempel:

type
  AInteger = Array of Integer; // denne type skal bruges i både FjerneGenGangere-proceduren og Button1Click-proceduren, hvorfor den skal være længere oppe i din kode end begge procedurere.

procedure FjernGenGangere(var A: AInteger);
var
  I: Integer;
  AInt: AInteger;
begin
  SetLength(AInt, 0);
  for I := Low(A) to High(A) do
  begin
    if I = Low(A) then
    else if A[I] <> A[I - 1] then
    begin
      SetLength(AInt, Length(AInt) + 1);
      AInt[High(AInt)] := A[I];
    end
    else if A[I] <> A[I - 1] then
    begin
      SetLength(AInt, Length(AInt) + 1);
      AInt[High(AInt)] := A[I];
    end;
  end;
  A := AInt;
end;

Desuden skal Button1Click-proceduren erstattes med denne lidt ændrede version:

procedure TForm1.Button1Click(Sender: TObject);
var
  i, Len : Integer;
  a : AInteger;
begin
  len := Random(30);
  SetLength(a, Len);
  for i := Low(a) to High(a) do // Jens: Her var der en lille fejl, da din version svarede til at man skrev for i := Low(a) to Length(a) do, og Length(a) vil altid i et dynamisk array være en større end High(a). Faktisk kunne jeg ikke trykke på knappen uden at få fejl, inden jeg rettede denne fejl.
  begin
    if (i mod 6 = 0) and (i > 0) then
      a[i] := a[0]
    else
      a[i] := Random(500);
  end;

  Memo1.Lines.Add(ArrayToString(A));
  QuickSort(a);
  FjernGenGangere(a); // FjernGenGangere-proceduren virker kun i sorterede arrays, derfor skal den kaldes efter sorteringen.
  Memo1.Lines.Add(ArrayToString(A));
end;
Avatar billede tango42 Nybegynder
25. september 2003 - 12:57 #7
Jeg takker de herrer...
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester