Diskuze: Dynamické datové strukture
Člen
Zobrazeno 13 zpráv z 13.
//= Settings::TRACKING_CODE_B ?> //= Settings::TRACKING_CODE ?>
Trochu přesnější zadání by nebylo? A taky popis problému a konkrétní otázka typu: "Jak prohodit dvě položky v seznamu?" atd.
V pascalu máme naprogramovat program, do kterého uživatel zadává čísla. Čísla se mají pomocí ukazatelů seřadit od nejmenšího po největší a vypsat na obrazovku. Bohužel mi program funguje pouze pro pár čísel a nevím si celkově rady s napsáním kódu tak, aby fungoval pro libovolný počet čísel.
No musíš si to rozdělit na části. Budeš potřebovat nějaký ukončovací znak, po jehož zadání se přestane načítat a začne se řadit. Během načítání budeš muset pokaždé alokovat (pomocí new) nový prvek seznamu (pokud tedy máte používat seznam - "pomocí ukazatelů" může znamenat hodně věcí).
Pak bys ten seznam procházel a použil nějaký řadící algoritmus (podívej se - BubbleSort, QuickSort, SelectSort, ... nebo máte zadáno?). Jinak zrovna pro řazení bych seznam moc nepoužíval, ale jestli musíte, tak aspoň dvousměrně vázaný..
Oni ty prvky by se měli řadit rovnou při zadání, například první se zadá 1 ta se zaniluje a zadá se další prvek například 3 ta se taky zaniluje a jelikož je větší než 1 tak ukazatel z jedničky ukáže na 3, jenže když přijde najednou třeba 2 tak 1 ukáže na 2 a ta na 3. Jenže problém je v tom jak to naprogramovat.
Aha.. No to máš říct rovnou..
A máš tam chybu - když máš 1 a přijde 3, tak 1 ukazuje na 3. Když přijde 2, tak prvně jí nastavíš ukazatel na 3 a pak nastavíš ukazatel 1 na 2. Nakresli si to..
A jaký konkrétně máš problém to naprogramovat? Je to jen porovnávání a přiřazovaní..
Já si to kreslil několikrát právě. Ale v tom programování se zadrhnu. Na začátku programu si deklaruju 3 různý ukazatele p,z a pomocný ukazatel pom. Teď tam mam New z to je první číslo takže přijde například 1 ta se zaniluje. Teď tam mam repeat aby to fungovalo pro nekonečně mnoho číslo a New pom která mi ukazuje na první číslo to znamená na z. Další je New p přečtu od uživatele např 2 a taky zaniluju. A teď začínají problémy. ptám se pokud je číslo menší než 1 tak ukazatel u p ukazuje na číslo z a z:=p; Pokud je větší tak tam mám další repeat a ptám se jestli je to číslo pom což je začátek různé od nilu. 1 je zanilovaná a proto se ukáže na dvojku. z^.dalsi:=p; Zatím to funguje. Zadám třetí číslo a to číslo 3. je větší jednička není zanilovaná takže pomocná se posune o jednu tudíž ukazuje na dvojku. Ptám se je 3 větší než 2? ano je takže se dvojkou ukáže na 3. Pořád funguje. Přidám číslo 4. je větší než 1 ta není zanilovaná takže se pomocná posune a ptá se jestli je 4 větší než 2 a to je takže se místo 3 přiřadí 4 a trojka mi vypadne ze seznamu. Nevím jak to naprogramovat tak abych nemusel rozepisovat stále ten kód pro více čísel ale aby se opakoval a fungoval pro jakékoliv množství čísel. Vím že tam je právě chyba ale nevím jak jí předejít.
Nechceš sem ten kód vložit jako text? Je tu na to tlačítko </>
program ukazate2;
Type uk=^objekt;
objekt=record
cislo:integer;
dalsi:uk;
End;
Var a,b,c :integer;
p:uk; z:uk; pom:uk;
begin
New(z);
Readln(z^.cislo);
z^.dalsi:=nil;
repeat
New(pom);
pom:=z;
New(p);
Readln(p^.cislo);
p^.dalsi:=nil;
if (p^.cislo <= pom^.cislo) then
begin
p^.dalsi:=z;
z:=p;
end
else
repeat
if pom^.dalsi<>nil then
begin
pom:=pom^.dalsi;
if p^.cislo > pom^.cislo then
begin
pom^.dalsi:=p;
end
else
begin
z^.dalsi:=p;
p^.dalsi:=pom;
end;
end
else z^.dalsi:=p;
until p^.dalsi=nil;
until p^.cislo=0;
p:=z;
writeln('Cisla');
repeat
begin
writeln(p^.cislo);
p:=p^.dalsi;
end;
until p=nil;
readln();
end.
Nějak takhle by to mohlo vypadat (kdyžtak si to otevři v nějakém chytrém editoru a nastav velikost tabulátoru na 2):
program ukazate2;
Type uk=^objekt;
objekt = record
cislo:integer;
dalsi:uk;
End;
Var
aktivni:uk; zacatek:uk; pom:uk;
begin
(*inicializace seznamu*)
aktivni := nil;
zacatek := nil;
Readln(cislo);
if cislo > 0 then
begin
(*prvni prvek*)
New(pom);
pom^.cislo := cislo;
zacatek := pom;
pom^.dalsi := nil;
(*vkladat cisla, po vlozeni nuly cyklus skonci*)
repeat
Readln(cislo);
if cislo > 0 then
begin
New(pom);
pom^.cislo := cislo;
(*pruchod seznamem*)
aktivni := zacatek;
while aktivni^.dalsi <> nil do
begin
if pom^.cislo >= aktivni^.cislo then (*vlozit prvek za nasledujici*)
begin
pom^.dalsi := aktivni^.dalsi;
aktivni^.dalsi := pom;
break; (* nebo co se to v Pascalu pouziva na ukonceni cyklu *)
end
else
aktivni := aktivni^.dalsi; (* prejit na dalsi prvek*)
end;
end;
end;
until cislo = 0;
end;
writeln('Cisla');
aktivni := zacatek;
if aktivni <> nil then
while aktivni^.dalsi <> nil do
begin
writeln(aktivni^.cislo);
pom = aktivni;
aktivni := aktivni^.dalsi;
free(pom); (*uklidit po sobe*)
end;
readln();
end.
A doporučuju si hodně programovat ve volném čase a naučit se taky nějakou teorii.. Za funkčnost neručím - v Pascalu jsem dlouho nedělal a nezkoušel jsem to přeložit..
Jo a aby to fungovalo, tak jako první musí být minimální možné číslo - tedy 1.. Kdyžtak si tam dodělej podmínku, aby to vložilo na začátek, pokud je cislo menší než zacatek^.cislo..
Vložení na začátek uděláš takto:
new(pom);
pom^.dalsi := zacatek;
zacatek := pom;
Bohužel mi to stále nefunguje, dostal jsem se sice už dál než sem byl ale nevím si stále rady..
Mám tu řešení
program ukazatele_serazeni;
Type uk=^objekt;
objekt=record
cislo:integer;
dalsi:uk;
End;
Var a,b,c :integer;
p,z,pom :uk;
begin
Writeln('Zadavejte cisla, az budete chtit skoncit zadejte nulu');
New(z);
Readln(z^.cislo);
z^.dalsi:=nil;
repeat
pom:=z;
New(p);
Readln(p^.cislo);
p^.dalsi:=nil;
repeat
if p^.cislo > pom^.cislo then
begin
if pom^.dalsi <> nil then
begin
if p^.cislo > pom^.dalsi^.cislo then
begin
pom:=pom^.dalsi;
end
else
begin
p^.dalsi := pom^.dalsi;
pom^.dalsi :=p;
end;
end
else
begin
pom^.dalsi:=p;
end;
end
else
begin
p^.dalsi:=pom;
z:=p;
end;
until (pom^.dalsi = p) or (p^.dalsi = pom);
until p^.cislo = 0;
p:=z;
writeln('Vase cisla od nejmensiho po nejvetsi:');
repeat
begin
writeln(p^.cislo);
p:=p^.dalsi;
end;
until p=nil;
readln();
end.
Zobrazeno 13 zpráv z 13.