Sortowanie przez wstawianie.

0

Program polega na wczytywaniu liczb z pliku txt (liczby po enterze). Chodzi aby program pobrał je z pliku, posortował i zapisał do innego pliku.
Witam udało mi się napisać coś takiego ale niestety nie działa (problem w wyświetlaniem wczytanych liczb):
Siedze prawie cały dzień i jestem laikiem od razu mówię. Proszę bardzo nie krytykować :)

procedure TForm1.Button3Click(Sender: TObject);      //procedura do przycisku POSORTUJ LICZBY
type
a1=array [1..9999] of integer;
b1=array [1..9999] of integer;
var
LICZ:TStringlist;
N: integer;
t:text;
w:integer;
i,j,s:integer;
a:a1;
b:b1;
function fp(x,y : integer) : boolean;
begin
  fp := (x <= y)
end;
begin
LICZ:= TStringlist.Create;
LICZ.LoadFromFile('przedsortowaniem.txt');
N:=LICZ.Count-1;
LICZ.Free;
ShowMessage(FloatToStr(N));
begin
AssignFile(t, 'przedsortowaniem.txt');
reset(t);
for i:=0 to N do
begin
readln(t,w);
a[i]:=w;
end;
for i := N - 1 downto 1 do
  begin
    j := i + 1;
    while (j <= N) and not fp(a[i],a[j]) do
    begin
      a[j-1] := a[j];
      inc(j);
    end;
    a[j - 1] := a[i];
  end;
for i := 1 to N do ShowMessage(i:4, b[i]:9, a[i]:9);
end;
end;                               

Prosił bym o informację co jet źle i co muszę poprawić.

0

Od razu mówię, że bez wyświetlania chodzi. Problem jest z wyświetlaniem.

1

Nie wgłębiałem się w kod, ale wskazać mogę co na pewno wedle mnie było i jest źle na pierwszy rzut oka w calym wątku, który musialem edytować.

  1. Bezsensowny tag. ludzie! Czy na prawdę nie możecie podawać konkretnie sam język?!
  2. Kod byl wstawiony w ogólne tagi, a nie konkretne kolioryzujące. A to jest nieczytelne.
  3. Kod nie jest sformatowany. Nieważne, że jest krótki. Ma być maksymalnie czytelny.

Poprawiłem poza formatowaniem, bo to powinien robić autor wątku. Następnym razem kiedy zobaczę taki wątek, powinien on polecieć do kosza. I to nie jest żart. Bo gdy ludziom o tym się wspomina, to wielkie zdziwienie. Ale jak mamy postąpić my Moderatorzy, skoro bez reakcji macie nasze uwagi w poważaniu.

Poza tym jest powód usunięcia o niskiej czytelności wątku, a to jest brakiem szacunku do potencjalnego czytelnika. Polecam zatem stosować się i sformatować swój kod porządnie. Jeśli nie umiesz samodzielnie są do tego odpowiednie narzędzia. Napisałem o tym przyklejony wątek. Ale po cóż spojrzeć. Ja mam problem to klękajcie narody, macie pomóc i tyle. Nieważne, żę się tego czytać nie da. Sorry, ale tak to często z mojej perspektywy wygląda. I to nieważne, czy to pierwszy czyjś czy ktoryś z kolei wątek na forum. I to nie tylko na tym :/

0

Bardzo mi przykro, dopiero zaczynam z programowanie. Chce się sam czegoś nauczyć ale no po prostu mi nie wychodzi. Bardzo byłbym wdzięczny za pomoc.

1

tak na pierwszy rzut oka to trochę bezsensownym jest dwukrotny odczyt pliku
skoro już masz go w stringliście 'LICZ' , to użyj jej do zapełnienia tablicy "a"

for i=0 to licz.count-1 do 
  try 
     a[i+1]:=strtoint(licz[i]);
  except
     // tu  obsługa wyjątku w sytuacji gdyby string licz[i] nie był znakową reprazentacją wartości typu integer 
  end;

po drugie :
pętla

for i:=0 to N do
begin
 readln(t,w);
 a[i]:=w;
end;

nie może się wykonać prawidłowo , bo z deklaracji typu 'al' wynika że jest indeksowany od jeden , a Ty w pierwszym przejściu pętli robisz podstawienie pod element z indeksem zero , do tego robisz podstawienie dla N+1 elementów. Albo masz pętlę od zera i kończysz na N-1 , albo od jeden do N. Przy włączonej opcji kompilatora "Range checking" miał byś komunikat o wyjściu poza zakres tablicy: a[0]

po trzecie : w jakim celu definiujesz dwa identyczne typy 'al' i 'bl' i do tego zmienną 'b' typu 'bl' pod którą nic nie podstawiasz , ale próbujesz ją wyświetlić w funkcji 'showmessage'

po czwarte : argumentem funkcji 'showmessage' jest tekst (string) , kod który podałeś nawet się nie skompiluje

0

Witam poownie a jak zapisać tą tablice do pliku posortowane.txt

Napisałem coś takiego:

  AssignFile(TF, 'posortowaniu.txt');
  ReWrite(TF);
  Writeln(TF, a[i]);
  CloseFile(TF);

ale wyświetla mi tylko 1 posortowaną liczbę.

0

zapis musisz robić w pętli

0

Mógłbym prosić o jakiś przykładowy kod wtedy pokombinuję i zrobię go pod swój skrypt? Bo nie wiem jak przypisać pętle pod zmienną. Bo jak mam zmienna to ja podstawie pod

writeln(TF, a[i]);

a[i] i wtedy mi wpisze to do pliku.

Z góry dzięki :)

0

Wpisujesz jedną: Writeln(TF, a[i]); a chcesz aby pojawiły się wszystkie?

0
for i:=low(a) to high(a) do
  Writeln(TF, a[i]);
0

Dobra wszystko super pięknie :) tylko wyświetla mi nie wiadomo jakie liczby. Do tablicy wczytuje poprawnie.

0

Oznacza to że twoje sortowanie, robi generowanie ... "nie wiadomo jakie liczby" ... zamiast sortowania.

0

Czyli rozumiem, że w tym przypadku kod:

for i := N - 1 downto 1 do
  begin
    j := i + 1;
    while (j <= N) and not fp(a[i],a[j]) do
    begin
      a[j-1] := a[j];
      inc(j);
    end;
    a[j - 1] := a[i];
  end;       

jest bezużyteczny bo generuje a nie sortuje tak?

0

Dokładnie tak.

0

Ogólnie ten kod, który wrzuciłem wyżej znajdował się na 2 stronach i oba podpisane były jako sortowanie.

Dobra napisałem coś takiego i mi sortuje :)

for j := N - 1 downto 0 do
begin
  x := a[j];
  i := j + 1;
  while (i <= N) and (x > a[i]) do
  begin
    a[i - 1] := a[i];
    inc(i);
  end;
  a[i - 1] := x;
end;
  listBox1.Items.Clear();
    AssignFile(t, 'posortowaniu.txt');
  ReWrite(t);
for i:=low(a) to high(a) do
  Writeln(t, a[i]);
  CloseFile(t);
end;
end;             

tylko mam 2 małe problemy :(
po kliknięciu 2 raz przycisku aby wykonywał tą czynność wyrzuca błąd w:

for i:=low(a) to high(a) do

oraz posortuje mi liczby ale pod nimi wyrzuca mi te generowane :(

0

zmień

for i:=low(a) to high(a) do

na

for i:=1 to N do 

bo zapełniasz tylko N pierwszych elementów tablicy A

0

pokaż cały kod podpięty pod przycisk

0

Zamykasz plik po wpisaniu do niego pierwszej liczby.

0

Wrzucam cały kod który ja wypociłem a dzięki wam działa :P

unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    Label5: TLabel;
    ListBox1: TListBox;
    ListBox2: TListBox;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);      //procedura do przycisku WYSWIETL NIEPOSORTOWANY PLIK
var
   PLIK: TextFile;                                   //zmienna do pliku
   S: String;                                        //zmienna do zawartosci
begin
     assignFile(PLIK, 'przedsortowaniem.txt');       //przypisanie zmiennej
if not FileExists('przedsortowaniem.txt') Then       //sprawdzenia czy plik istnieje
begin
     ShowMessage('Taki plik nie istnieje!');         //wyrzuca wiadomosc ze plik nie istnieje
end
else
begin
     listBox1.Items.Clear();                         // zabezpieczenie przycisku aby nie dodawalo ponownie zawartosci pliku
     AssignFile(PLIK, 'przedsortowaniem.txt');       //zmienna do pliku jesli plik w folderze istnieje
     reset(PLIK);                                    //reset pliku
while not Eof(PLIK) do
begin
     readln(PLIK, S);                                //odczyt pliku
     listBox1.Items.Add(S);                          //wyswietla w TListBoxie dane z pliku
end;
end;
end;

procedure TForm1.Button3Click(Sender: TObject);      //procedura do przycisku POSORTUJ LICZBY
type
  a1=array [0..9999] of integer;
var
  LICZ:TStringlist;
  t:text;
  N,w,i,j,x:integer;
  a:a1;
begin
  LICZ:= TStringlist.Create;
  LICZ.LoadFromFile('przedsortowaniem.txt');
  N:=LICZ.Count-1;
  LICZ.Free;
  ShowMessage(FloatToStr(N));
begin
  AssignFile(t, 'przedsortowaniem.txt');
  reset(t);
for i:=0 to N do
  begin
    readln(t,w);
    a[i]:=w;
  end;
for j := N - 1 downto 0 do
  begin
    x := a[j];
    i := j + 1;
      while (i <= N) and (x > a[i]) do
        begin
          a[i - 1] := a[i];
          inc(i);
        end;
      a[i - 1] := x;
  end;
  AssignFile(t, 'posortowaniu.txt');
  ReWrite(t);
for i:=0 to N do
  Writeln(t, a[i]);
  CloseFile(t);
end;
end;

procedure TForm1.Button2Click(Sender: TObject);      //procedura do przycisku WYSWIETL POSORTOWANY PLIK
var

   PLIK2: TextFile;                                  //zmienna do pliku
   S: String;                                        //zmienna do zawartosci
begin
     assignFile(PLIK2, 'posortowaniu.txt');           //przypisanie zmiennej
if not FileExists('posortowaniu.txt') Then           //sprawdzenia czy plik istnieje
begin
     ShowMessage('Taki plik nie istnieje!');         //wyrzuca wiadomosc ze plik nie istnieje
end
else
begin
     listBox2.Items.Clear();                         // zabezpieczenie przycisku aby nie dodawalo ponownie zawartosci pliku
     AssignFile(PLIK2, 'posortowaniu.txt');          //zmienna do pliku jesli plik w folderze istnieje
     reset(PLIK2);                                   //reset pliku
while not Eof(PLIK2) do
begin
     readln(PLIK2, S);                               //odczyt pliku
     listBox2.Items.Add(S);                          //wyswietla w TListBoxie dane z pliku
end;
end;
end;

end.
0

Wklejam jeszcze raz , po sformatowaniu , niby to samo ale czyta się zupełnie inaczej .
Tyle że ten kod różni się od tego z poprzedniego postu nie tylko formatowaniem .
Albo pokażesz kod , który naprawdę sprawia problem, albo bedziesz za kazdym razem wrzucał cos innego , ale wtedy nikt się nie będzie bawił w zgadywanie który o który kod Ci chodzi .

procedure TForm1.Button3Click(Sender: TObject); // procedura do przycisku POSORTUJ LICZBY
type
  a1 = array [0 .. 9999] of integer;
var
  LICZ: TStringlist;
  t: text;
  N, w, i, j, x: integer;
  a: a1;
begin
  LICZ := TStringlist.Create;
  LICZ.LoadFromFile('przedsortowaniem.txt');
  N := LICZ.Count - 1;
  LICZ.Free;
  ShowMessage(FloatToStr(N));
  begin
    assignFile(t, 'przedsortowaniem.txt');
    reset(t);
    for i := 0 to N do
    begin
      readln(t, w);
      a[i] := w;
    end;
    for j := N - 1 downto 0 do
    begin
      x := a[j];
      i := j + 1;
      while (i <= N) and (x > a[i]) do
      begin
        a[i - 1] := a[i];
        inc(i);
      end;
      a[i - 1] := x;
    end;
    assignFile(t, 'posortowaniu.txt');
    ReWrite(t);
    for i := 0 to N do
      Writeln(t, a[i]);
    CloseFile(t);
  end;
end;
0

Ok będę pamiętał. Do tego pytanko jakiego programu używasz do formatowania kodu?

0

do tego problem z:
for i := 0 to N do
nadal występuje po ponownym naciśnięci tego samego przycisku.

Co mogę podmieć pod CloseFile? Znowu zrobić pętlę, że przy ponownym kliknięciu zaczyna algorytm od nowa?

0

formatowanie załatwia mi środowisko IDE , w moim przypadku D2010

2

Masz dwa razy AssignFile zaś CloseFile tylko raz - stąd problem.

0

ponadto określasz liczbę elementów tablicy na N elementów , a zapisując i czytając z pliku operujesz na N+1 elementach ..

for i := 0 to N do 
0

No dobra jest poprawione:

procedure TForm1.Button3Click(Sender: TObject); // procedura do przycisku POSORTUJ LICZBY
type
  a1 = array [0 .. 9999] of integer;
var
  LICZ: TStringlist;
  t: text;
  N, w, i, j, x: integer;
  a: a1;
begin
  LICZ := TStringlist.Create;
  LICZ.LoadFromFile('przedsortowaniem.txt');
  N := LICZ.Count;
  LICZ.Free;
  ShowMessage('Posortowano ' + FloatToStr(N) + ' liczb!');
  begin
    assignFile(t, 'przedsortowaniem.txt');
    reset(t);
    for i := 1 to N do
    begin
      readln(t, w);
      a[i] := w;
    end;
    for j := N - 1 downto 1 do
    begin
      x := a[j];
      i := j + 1;
      while (i <= N) and (x > a[i]) do
      begin
        a[i - 1] := a[i];
        inc(i);
      end;
      a[i - 1] := x;
    end;
    assignFile(t, 'posortowaniu.txt');
    ReWrite(t);
    for i := 1 to N do
    begin
      Writeln(t, a[i]);
    end;
    CloseFile(t);
  end;
end;                     

ale:

CloseFile(t);

nie wiem w którym momencie mam umieścić ;/

0

Tam gdzie już nie potrzebujesz otwartego pliku.

0

No dobra jest poprawione

begin
  LICZ := TStringlist.Create;
  LICZ.LoadFromFile('przedsortowaniem.txt');
  N := LICZ.Count;
  LICZ.Free;
  ShowMessage('Posortowano ' + FloatToStr(N) + ' liczb!');
  begin
    assignFile(t, 'przedsortowaniem.txt');
    reset(t);
    for i := 1 to N do
    begin
      readln(t, w);
      a[i] := w;
    end;
    CloseFile(t);
    for j := N - 1 downto 1 do
    begin
      x := a[j];
      i := j + 1;
      while (i <= N) and (x > a[i]) do
      begin
        a[i - 1] := a[i];
        inc(i);
      end;
      a[i - 1] := x;
    end;
    assignFile(t, 'posortowaniu.txt');
    ReWrite(t);
    for i := 1 to N do
    begin
      Writeln(t, a[i]);
    end;
    CloseFile(t);
  end;
end;

ale problem z:

for i := 1 to N do

nadal występuje przy ponownym naciśnięciu przycisku :(

0

co rozumiesz jako :
"problem z for i := 1 to N do "
??

0

Przy uruchomieniu buttona sortuje, następnie klikam button wyswietl posortowane liczby. Jak najbardziej wyswietla.
Ale chciałem sprawdzić co będzie jak klikne jeszcze raz aby posortowalo. Po kliknięciu wywala mi błąd w linijce:

for i := 1 to N do 

RunError5

1 użytkowników online, w tym zalogowanych: 0, gości: 1