» »

[Delphi] lexicographic order

[Delphi] lexicographic order

mISOk ::

Zdravo!

Imam eno težavo. Kako najhitreje leksiografsko urediti string. Znima me, če kdo pozna kakšen algoritem za takšno stvar. Ali je že kdo kje slišal za to, kakšen link do rešitve oz. knjiga...
String je namreč velik (do 46 znakov) zato kakšen trivialen algoritem odpade.

primer :
niz "210054" je leksiografsko urejen : "005421"
oz.
niz "dgber" je leksiografsko urejen : "berdg"
...
LP

[edit - preberi me!!! - vsc]
=]
  • spremenil: Vesoljc ()

OwcA ::

Nekateri jeziki to znajo že s priloženimi knjižnivami, ali so prepočasni?
Otroška radovednost - gonilo napredka.

Thomas ::

Prevedi v niz, posortaj ga in potem nazaj v string.

mISOk ::

Zdravo!

Thomas ne vem kaj točno misliš s tem "Prevedi v niz, posortaj ga in potem nazaj v string".

Owca trenutno delam v Delphi-ju 6 pa nisem zasledil, da bi zmogel lexicographic order. Bom še malo bolj povrtal v Delphi in če zmore bo vrejetno kar ok (takšni implementirani algoritmi ponavadi niso čisto trivialni).

LP
=]

OwcA ::

Niz (string) je skoraj gotovo tako ali tako implementiran kot polje (array) znakov. Vse kar moraš narediti je, da to polje urediš (čisto klasično urejanje), pri čemer uporabiš za primerjanje elementov leksiografsko primerjanje. S kakšnim quick sortom (O(n logn)) bi moralo iti kar hitro.
Otroška radovednost - gonilo napredka.

mISOk ::

Zdravo!

To je že res o tem ni dvoma. Ampak to ni leksiografsko urejen niz, ki ga jaz želim. Če si pogledal moj primer

niz "210054" je leksiografsko urejen : "005421". Če pa bi uporabil navaden sort bi dobil "001245". torej določen niz moram s shiftiranjem spremeniti v niz, ki je leksiografsko najmanjši.

Takšan trivialna funkcija že naredi prav, ampak je časovno zelo potratna.

function lex_sort(s:string):string;
var x,y:integer;
min,hr1,hr2,st:string;
begin
//dolžina niza
x:=length(s);
min:=s;
for y:=1 to (x-1) do
begin
//šiftam za y okoli
hr1:=copy(s,x-y+1,y);
hr2:=copy(s,1,x-y);
st:=hr1+hr2;
//če je novo nastali string manjši od min
if (st (manjše) min) then min:=st;
end;
result:=min;
end;


Zanima me, če kdo pozna kakšno hitrejšo funkcijo (ki naredi enako), saj bom ta del kode izvajal relativno pogosto.

Hvala za pomoč.
LP
=]

OwcA ::

Saj sem rekel, da za primerjanje uporabiš leksikografsko relacijo urejenosti. Pomaga tudi, če uporabiš malo boljši algoritem za urejanje.
Otroška radovednost - gonilo napredka.

Zgodovina sprememb…

  • spremenilo: OwcA ()

mISOk ::

OK!

Ne vem, če se razumema prav.

Če bi uporabil navaden sort (quick, bubble,...) ne bi dobil željenega rezultata. Zato takšno urejanje odpade.

Zgoraj napisana fukcija ne dela tega, ker vse skupaj shiftira in preglejuje ali dobljeni string leksiografsko najmanjši glede na prejšnje. Fukcija je trivialna in zato zelo počasna.

Ne vem pa kaj misliš, "da za primerjanje uporabiš leksikografsko relacijo urejenosti".

LP
=]

OwcA ::

Glej, ko ti kakorkoli urejaš, uporabiš neko relacijo urejenosti, na podlagi katere se odločiš kateri element bolj ustreza danim kriterijem (je večji). Če namesto navadega večje-manjše uporabiš leksikografski večje manjše, boš uredil nameso klasično uredil leksikografsko, še vedno pa lahko za to uporabiš quick sort ali kaj podobnega (odvisno od tega kako raznorodni so nizi, ki jih boš urejal).
Otroška radovednost - gonilo napredka.

mISOk ::

OK!

Nisma se zaštekala. Verjetno sem slabo opisal problem (moja slaba lastnost).

Jaz ne urejam več nizov med sabo, ampak želim en niz urediti tako, da ga zapišem kot leksiografsko najmanjši niz. Torej niz s šiftanjem obračam ("fghjk" - shift za 1 dobim - "ghjkf") tako dolgo dokler ne dobim leksiografsko najmanjši niz.

To tudi dela tista funkcija. Hočem ugotoviti ali obstaja hitrejša funkcija, ki bi mi opravila enako.

LP
=]

OwcA ::

Jst tebe že razumem, ti mene ne. ;)

Niz tako urediš, da premetavaš črke. Vprašanje je le na podlagi česa jih premetavaš.
Otroška radovednost - gonilo napredka.

mISOk ::

Nisem glih siguren, da ti mene štekaš. :D ;)


Črk ne morem premetavati lahko jih le šiftiram (ampak vse skupaj). Torej ne morem narediti iz "adaabbbce" = "aaabbbcde" ampak lahko ta niz preoblikujem le tako, da dobim nize "daabbbcea", "aabbbcead", "abbbceada","bbbceadaa", "bbceadaab", "bceadaabb", "ceadaabbb", "eadaabbbc".

Iz teh pa izberem leksiografsko najmanjšega.

LP
=]

Zgodovina sprememb…

  • spremenil: mISOk ()

Vesoljc ::

niz "210054" je leksiografsko urejen : "005421"
oz.
niz "dgber" je leksiografsko urejen : "berdg"

lahko za zacetek poves po kakem pravilo je to urejeno?
Abnormal behavior of abnormal brain makes me normal...

mISOk ::

niz "210054" je leksiografsko MINIMALEN niz : "005421"
oz.
niz "dgber" je leksiografsko MINIMALEN niz : "berdg"

Moja napaka v napisu!
=]

64202 ::

Vesoljc: stringe lahko samo rotiras, mISOk se je mau nejasno izrazil

OwcA ::

Hočeš reči, da imaš neko posebno dodatno omejitev in izmed cikličnih permutacij danega niza iščeš leksikografsko najmanjšega? Tiste ciklične permutacije so precej pomemben podatek in bi si zaslužil omembo že v prvem odgovoru.
Otroška radovednost - gonilo napredka.

mISOk ::

Se strinjam, da se nisem pravilno izrazil.

Upam, da me zdaj razumete.
=]

podtalje ::

Sam algoritem boš težko kaj izboljšal, izboljšaš pa lahko, kako je napisano.

Kot prvo, jaz ne bi uporabljal funkcije copy(), ampak bi raje naredil prostor za še enkrat daljši niz
ter potem prvo črko metal na konec stringa, v eni spremenljivki pa bi spremljal, katera je dejansko prva črka.

Druga ključna funkcija pa je leksiografsko primerjanje dveh stringov, ki mora takoj ko najde prvi večji znak,
vrniti rezultat (da ne boš slučajno gledal cel string do konca)

Gundolf ::

Kaj pa če najprej poiščeš lexikografsko najmanjši znak (zahtevnost O(n)). Če je le eden, potem se niz začne z njim. Npr: dgber, najmanjši je b, zato zarotiraš niz tako da se začne z b -> (dg)(ber) -> berdg

Če najdeš več najmanjših znakov, potem pogledaš še znake za njimi (zahtevnost spet O(n)): 210054, najmanjši je 0 (se pojavi 2x), za prvo 0 je tudi 0, za drugo 0 je 5, zato izbereš za začetek prvo -> (21)(0054) -> 005421

... in tako dalje ...

V nekako realnih (neizrojenih) nizih boš imel zelo zelo hiter algoritem.

OwcA ::

Sam bi pustil niz kot je in samo preračunaval kazalec na prvi element. Generiranje vseh cikličnih permutacij je tako O(n) problem in se poslužil tega kar svetuje Gundolf.
Otroška radovednost - gonilo napredka.

Zgodovina sprememb…

  • spremenilo: OwcA ()

mISOk ::

Hvala za nasvete!

Jih bom upošteval. Se grem kar lotit pisanja.

LP
=]


Vredno ogleda ...

TemaSporočilaOglediZadnje sporočilo
TemaSporočilaOglediZadnje sporočilo
»

Pomoč pri Javi

Oddelek: Programiranje
11728 (528) Spura
»

python-pomoč pri nalogi z nizi

Oddelek: Programiranje
181430 (1128) galu
»

Generiranje kombinacij znakov

Oddelek: Programiranje
141221 (906) c0dehunter
»

[JavaScript] Sortiranje šumnikov

Oddelek: Programiranje
152006 (1740) MarkookraM
»

Problem (za Stratosa?)

Oddelek: Programiranje
372188 (1538) Thomas

Več podobnih tem