Minulla on kaksi stringlistia. Ensimmäisessä stringlistissa (stringlist1) on 500 000 stringia. Toisessa stringlistissa (stringlost2) on 1500000 stringia. Ensimmäisen listan stringit on toisen stringlistan stringien osajoukko. Olen yrittänyt tehdä algoritmia ja silmukkaa jolla poistaisin stringlist1:ssa esiintyvät stringit stringlist2:sta jolloin siis stringlist2:een jäisi miljoona stringiä.
Ongelma on tuhoton hitaus. Tein algoritmin delphilla:
For i:=0 to stringlist1.count do Stringlist2.delete(stringlist2[indexOf(stringlist1[i]]);
Jolloin se looppaa 1.5 miljoonaa kertaa stringlist1:n läpi mikä ei ole tuhottoman hidasta. Hitaus ilmeisesti tulee kun se vertaa jokaisen kohdalla mistä kohtaa stringlist2:ta se stringi löytyy, mikä sen indeksi on jotta sw tietää tuhota oikean stringin. En tiedä miten delphi 10.3 tämän haun toteuttaa oletuksena. Listit on periaatteessa sortattu ohjelman ulkopuolella, tosin en tiedä miten tietokone tämän sorttauksen tulkitsee koska jokaisessa stringissä on sekä numeroita että kirjaimia (13 merkkiä kussakin).
Mikä algoritmi voisi nopeuttaa tätä vai voisko mikään? Auttaisko jotenkin vertailla stringin ekoja merkkejä ja koittaa jakaa stringlist2:ta osiin ja tutkia missä osassa stringi siellä on jotta täytyisi käydä läpi pienempää listia? Tosin tuleehan siinä sit ne if-lauseet. Vai voisiko koko roskan toteuttaa muussa muodossa kuin stringlist? Joku dictionary jossa on nopeampi haku? Miten se toreutettas 15 merkin stringeillä?
Samojen stringien poisto stringlistista
39
50
Vastaukset
- Anonyymi
Luo kokonaan uusi list3 kahlaten list1:stä sen mukaan löytyykö sille tupla list2:ssa.
- Anonyymi
Meld taitaa olla sinulle sopiva metodi. :
https://askubuntu.com/questions/515900/how-to-compare-two-files - Anonyymi
Jos stringisi ovat järjestyksessä, sitä voidaan kyllä nopeuttaa huomattavasti (ja noin isoilla listoilla on luultavasti tehokkaampaa järjestää (O(n*log(n)) listat ensin, ja sen jälkeen poistaa ylimääräiset stringit järjestetyistä listoista (O(n)), kuin suoraan lähteä poistamaan stringejä satunnaisjärjestyksessä (O(n^2)).
Jos jostain syystä haluat säilyttää stringien alkuperäisen järjestyksen, niin ei sitä oikein voi tuosta O(n^2):sta parantaa.- Anonyymi
Voihan sen järjestyksen ensin tallentaa, sitten tehdä järjestystavalla ja lopuksi järjestää uudelleen tallennetun järjestyksen avulla.
- Anonyymi
Anonyymi kirjoitti:
Voihan sen järjestyksen ensin tallentaa, sitten tehdä järjestystavalla ja lopuksi järjestää uudelleen tallennetun järjestyksen avulla.
No se on totta.
- Anonyymi
Sellainen lisähuomio vielä, että yleensä kannattaa miettiä myös pidemmällä tähtäimellä, mitä haluaa ohjelmissaan tehdä. Jos poimit kolmasosan string-listastasi toiseen listaan ja haluat poistaa ne sitten alkuperäisestä listasta, niin nuo molemmat kannattaa tehdä samalla kertaa (ellei ole jotain syytä, miksi niin ei voisi tehdä). Eli samalla kun lisäät stringlist2:een stringin, poista se stringlist1:stä. Silloin et joudu käymään listoja läpi yhtäkään ylimääräistä kertaa.
- Anonyymi
Anonyymi kirjoitti:
No se on totta.
Ei ubuntussa tarvitse stringlistissa, se toimii ilmankin.
- Anonyymi
Eikö täällä ole enää muita kuin ubuntun käyttäjiä.
- Anonyymi
sudo apt install meld && meld
tai heti komennolla: diff stringlist1 stringlist2- Anonyymi
Ei tässä haettu samaa asiaa jonkun toisen koodaamana, vaan tehokkaampaa tapaa tehdä se.
- Anonyymi
meld tekee yhdistelmä listoja, ei mitään apua tässä tehtävässä.
- Anonyymi
diff on meld työkaluun nähden käänteinen, ja siitä olisi apua, mutta tulostus täytyisi siistiä.
- Anonyymi
Mikään hakualgoritmit, lajittelualgoritmit tai valinta-algoritmit muutokset eivät merkittävästi nopeuta käsittelyä.
Käsittelyn ajaksi katkaistu yhteys graafisen komponentin tilanpäivityksiin nopeuttaa.
Myös käsittelyn luovuttaminen ulkoiselle komennoille (diff: suosittelen) nopeuttaa merkittävästi. Useita minuutteja vievä lajittelu, on valmis alle 2 sekunnin.- Anonyymi
Ehdottomasti kaikki ylimääräinen grafiikka kannattaa riisua, ja sillä voi olla yllättävänkin suuri vaikutus. Riittävän isolla datamäärällä (miljoona riviä on jo varsin paljon) algoritmin valinta on kuitenkin ylivoimaisesti merkittävin tekijä.
Jos n = 1 000 000, niin O(n^2)-algoritmi, vie noin biljoona aikayksikköä, kun taas O(n*log(n)) vie vain kymmenen miljoonaa aikayksikköä, eli aikavaativuus putoaa sadastuhannesosaan vaihtamalla tehokkaampaan algoritmiin. - Anonyymi
Esimerkkinä lajittelusta, jossa 559 610 (yli puoli miljoonaa) merkkijonoa lajitella pituusjärjestykseen (pisin viimeiseksi), vie hiukan yli puoli sekuntia (real 0,630s).
Tulos saavutetaan kun lajittelu ulkoistetaan cat, awk, sort ja cut komentojen yhteiseksi tehtäväksi. - Anonyymi
Anonyymi kirjoitti:
Esimerkkinä lajittelusta, jossa 559 610 (yli puoli miljoonaa) merkkijonoa lajitella pituusjärjestykseen (pisin viimeiseksi), vie hiukan yli puoli sekuntia (real 0,630s).
Tulos saavutetaan kun lajittelu ulkoistetaan cat, awk, sort ja cut komentojen yhteiseksi tehtäväksi.Aivan riippumatta siitä, miten sen käytännössä toteutat (itse koodaten vai muiden palikoilla leikkien), algoritmi on se, millä on väliä. Jos käsittelet miljoonan rivin datan O(n^2)-algoritmilla, se vie (noin) sata tuhatta kertaa kauemmin kuin O(n*log(n))-algoritmilla.
- Anonyymi
Keksin että yksi avainsana oli binary search. En ole vielä tarkastanut toimiiko se oikein mutta Delphin TStringList.Find käyttää binääristä hakua kun IndexOf käytti lineaarista. Ensin TStringList.sort niin StringList sortataan (en tiedä miten se konekielitasolla menee kuin 15 merkin jono sortataan). Tämän jälkeen Find funktio palauttaa index-parametrina poistettavan stringin indeksin toisella listilla jotta se voidaan deletoita. Näyttää tunnin algoritmi putoavan muutamaan minuuttiin.
Muita vaihtoehtoja voisi olla kuulemma järjestysluvullinne array. Pitäisi päästä vertailemaan järjestyslukuja, jolloin se olisi yksi komento tai yksi kohta muistissa, ei vertailemaan 15 merkin merkkijonona. Joku hash list, dictionary tai joku. Tehostuisi ehkä vielä suhteessa binäärihakuun. - Anonyymi
Anonyymi kirjoitti:
Keksin että yksi avainsana oli binary search. En ole vielä tarkastanut toimiiko se oikein mutta Delphin TStringList.Find käyttää binääristä hakua kun IndexOf käytti lineaarista. Ensin TStringList.sort niin StringList sortataan (en tiedä miten se konekielitasolla menee kuin 15 merkin jono sortataan). Tämän jälkeen Find funktio palauttaa index-parametrina poistettavan stringin indeksin toisella listilla jotta se voidaan deletoita. Näyttää tunnin algoritmi putoavan muutamaan minuuttiin.
Muita vaihtoehtoja voisi olla kuulemma järjestysluvullinne array. Pitäisi päästä vertailemaan järjestyslukuja, jolloin se olisi yksi komento tai yksi kohta muistissa, ei vertailemaan 15 merkin merkkijonona. Joku hash list, dictionary tai joku. Tehostuisi ehkä vielä suhteessa binäärihakuun.Mitkään hakualgoritmit, lajittelualgoritmit tai valinta-algoritmit eivät ole varteen otettavia vaihtoehtoja, huippuunsa viritetylle ja juuri tätä tehtävää varten luodulle ulkoiselle komennolle.
Vai mitä olet mieltä, kun suoritamme "kai" -merkkijono haun, tiedostosta, joka sisältää yli puoli miljoonaa erilaista merkkijonoa, ja suoritus vie vain 0,017s, tuottaen tiedoston jossa on 5 917 löytynyttä.
Ei tätä voi nopeuttaa millään, siispä opettelemme ulkoistamaan tehtäviä tausta suorituksena. Ellet vielä osaa, nyt on korkea aika opetella. - Anonyymi
Anonyymi kirjoitti:
Mitkään hakualgoritmit, lajittelualgoritmit tai valinta-algoritmit eivät ole varteen otettavia vaihtoehtoja, huippuunsa viritetylle ja juuri tätä tehtävää varten luodulle ulkoiselle komennolle.
Vai mitä olet mieltä, kun suoritamme "kai" -merkkijono haun, tiedostosta, joka sisältää yli puoli miljoonaa erilaista merkkijonoa, ja suoritus vie vain 0,017s, tuottaen tiedoston jossa on 5 917 löytynyttä.
Ei tätä voi nopeuttaa millään, siispä opettelemme ulkoistamaan tehtäviä tausta suorituksena. Ellet vielä osaa, nyt on korkea aika opetella.Millä taikuudella sinä luulet niiden komentojen toimivan? Algoritmi on siellä taustalla joka tapauksessa, ja toki sellainen komento johon on käytetty järkevää algoritmia, kannattaa valita, mutta kyse on silti täsmälleen samasta asiasta: haluatko käyttää tehokkaampaa vai vähemmän tehokasta algoritmia.
Jos et itse osaa ajatella asiaa, joudut luottamaan sokeasti siihen, että juuri se sinun valitsemasi komento on sattumalta tehty tähän nimenomaiseen tapaukseen järkevällä algoritmilla. Jos osaat ajatella, voit toki käyttää satunnaista komentoa jos laiskottaa, tai sitten voit miettiä, mikä algoritmi on kyseiseen tehtävään paras, ja käyttää sitä, joko itse koodattuna tai jostain valmiista paketista löydettynä. - Anonyymi
Anonyymi kirjoitti:
Ehdottomasti kaikki ylimääräinen grafiikka kannattaa riisua, ja sillä voi olla yllättävänkin suuri vaikutus. Riittävän isolla datamäärällä (miljoona riviä on jo varsin paljon) algoritmin valinta on kuitenkin ylivoimaisesti merkittävin tekijä.
Jos n = 1 000 000, niin O(n^2)-algoritmi, vie noin biljoona aikayksikköä, kun taas O(n*log(n)) vie vain kymmenen miljoonaa aikayksikköä, eli aikavaativuus putoaa sadastuhannesosaan vaihtamalla tehokkaampaan algoritmiin.Poistin ruudulle tulostettan laskurin arvon joka siis käy yhdestä puoleentoistamiljoonaan ja nyt ei tulostu mitään tietoa missä mennään niin ohjelma nopeutui 40 minuutista 4 minuuttiin. Näyttäs toimivan. Mietityttää vaan voiko sillä olla niin iso ero ettei kirjoiteta tuota ruudulle? Vai pakko olla bugi? Mut toistaalta laitoin vain kommenttimerkit yhden rivin eteen.
- Anonyymi
Anonyymi kirjoitti:
Millä taikuudella sinä luulet niiden komentojen toimivan? Algoritmi on siellä taustalla joka tapauksessa, ja toki sellainen komento johon on käytetty järkevää algoritmia, kannattaa valita, mutta kyse on silti täsmälleen samasta asiasta: haluatko käyttää tehokkaampaa vai vähemmän tehokasta algoritmia.
Jos et itse osaa ajatella asiaa, joudut luottamaan sokeasti siihen, että juuri se sinun valitsemasi komento on sattumalta tehty tähän nimenomaiseen tapaukseen järkevällä algoritmilla. Jos osaat ajatella, voit toki käyttää satunnaista komentoa jos laiskottaa, tai sitten voit miettiä, mikä algoritmi on kyseiseen tehtävään paras, ja käyttää sitä, joko itse koodattuna tai jostain valmiista paketista löydettynä.Käyttöjärjestelmän komennot (grep) kuten tuossa edellisessä oli on vuosien työn tulos, jota hiotaan aina vain paremmaksi. Minä en luota omiin enkä sinun kykyihin tuottaa tehokkaampaa kuin olemassa olevat komennot jo on.
Myöskään itse komennon käyttämä algoritmi ei kiinnosta, riittää että on tehokas ja toimii. On erittäin tyhmää keksiä pyörä joka kerta uudestaan, kun vielä ottaa huomioon se tosiasian että itse tehtynä siitä tulisi merkittävästi huonompi, ja toteuttaminen veisi useita vuosia. - Anonyymi
Anonyymi kirjoitti:
Käyttöjärjestelmän komennot (grep) kuten tuossa edellisessä oli on vuosien työn tulos, jota hiotaan aina vain paremmaksi. Minä en luota omiin enkä sinun kykyihin tuottaa tehokkaampaa kuin olemassa olevat komennot jo on.
Myöskään itse komennon käyttämä algoritmi ei kiinnosta, riittää että on tehokas ja toimii. On erittäin tyhmää keksiä pyörä joka kerta uudestaan, kun vielä ottaa huomioon se tosiasian että itse tehtynä siitä tulisi merkittävästi huonompi, ja toteuttaminen veisi useita vuosia.Näistä tehoja vaativien tehtävien ulkoistamisesta, graafisen liittymän ulkopuolelle, on sekin hyöty että prosessien suoritus säikeisettään ja silloin tehtävä annetaan ytimelle, jolla sillä hetkellä on vähiten kuormaa.
- Anonyymi
Anonyymi kirjoitti:
Käyttöjärjestelmän komennot (grep) kuten tuossa edellisessä oli on vuosien työn tulos, jota hiotaan aina vain paremmaksi. Minä en luota omiin enkä sinun kykyihin tuottaa tehokkaampaa kuin olemassa olevat komennot jo on.
Myöskään itse komennon käyttämä algoritmi ei kiinnosta, riittää että on tehokas ja toimii. On erittäin tyhmää keksiä pyörä joka kerta uudestaan, kun vielä ottaa huomioon se tosiasian että itse tehtynä siitä tulisi merkittävästi huonompi, ja toteuttaminen veisi useita vuosia.Totta kai yksittäinen komento on (yleensä) optimoitu suurin piirtein niin tehokkaaksi kuin mahdollista. Jos sellainen on tarjolla siihen tehtävään, joka sinun pitäisi saada aikaan, se on todennäköisesti paras vaihtoehto.
Mutta tosiasia on kuitenkin se ettei joka ikiselle asialle, minkä joku joskus voisi kuvitella haluavansa tietokoneella tehdä, ole olemassa omaa yksittäistä komentoa, ja heti kun ketjutat edes kaksi (saati sitten useampia) komentoa, sinä luot uuden algoritmin, jonka palaset kyllä ovat tehokkaita, mutta kokonaisuus voi olla äärimmäisen typerä ja tehoton jos et yhtään osaa ajatella algoritmisesti. Jos valikoit nuo tehokkaat komennot niin, että lopputulos on O(n^2)-algoritmi, se on riittävän isolla datalla väistämättä huonompi ratkaisu kuin tehottomalla tavalla itse koodattu O(n*log(n))-algoritmi. Toki vielä parempi on jos osaat miettiä tehokkaiden komentojen käytön niin, että saat niillä toteutettua sen O(n*log(n))-algoritmin. - Anonyymi
Anonyymi kirjoitti:
Ehdottomasti kaikki ylimääräinen grafiikka kannattaa riisua, ja sillä voi olla yllättävänkin suuri vaikutus. Riittävän isolla datamäärällä (miljoona riviä on jo varsin paljon) algoritmin valinta on kuitenkin ylivoimaisesti merkittävin tekijä.
Jos n = 1 000 000, niin O(n^2)-algoritmi, vie noin biljoona aikayksikköä, kun taas O(n*log(n)) vie vain kymmenen miljoonaa aikayksikköä, eli aikavaativuus putoaa sadastuhannesosaan vaihtamalla tehokkaampaan algoritmiin.Koska kysymys on "yleistä ohjelmoinnista" -palstalla, se ei ota kantaa ohjelmointikieleen.
Delphissä:
Kannattaa huomata:
type
TStringList = class(TStrings)
...
end;
ja myös:
TMemoStrings = class(TStrings)
...
end;
TListBoxStrings = class(TStrings)
...
end;
nuo TMemoStrings ja TListBoxStrings ovat siis sinänsä ihan oikeita tyyppejä, mutta referenssit noihin ovat usein tyy ppiä TStrings .
siis esim:
var
SL : TStrings;
SL := Memo1.Strings;
ShowMessage(SL.Classname); // tulostaa "TMemoStrings"
SL := ListBox1.Items;
ShowMessage(SL.Classname); // tulostaa "TListBoxStrings"
Mitään hitaita operaatioita EI PIDÄ koskaan suorittaa suoraan TMemoStrings eikä TListBoxStrings -luokkien objekteille !
Jos hitaita operaatioita tarvitaan, suorita ne aina TStringList -luokan ilmentymälle eli objektille.
Lisäksi:
delete() on periaatteessa hidas operaatio, ja mitä lähempänä listan alkua poistettava merkkijono on, sitä hitaampi operaatio.
siis kannattaa mieluummin tehdä for i := SL.Count-1 downto 0 -silmukka.
Myös Sort() -operaatio muuttuu hitaaksi, jos listassa on satoja tuhansia merkkijonoja (tai jopa yli miljoona),
Jos listassa on vaikkapa katuosoitteita (siis alkaa kadun nimellä) niin kannattaa jakaa kukin alkukirjain erikseen ja tehdä useita TStringList -objekteja, yksi kullekin alkukirjaimelle. Kannattaa samalla harkita, kuinka haluaa käsitellä isot/pienet kirjaimet.
Olisi muuten testaamisen arvoinen asia:
Onko delete() tai insert() -operaatio nopeampi "linked list" -toteutuksessa verrattuna Delphin TStringList -luokan käyttämään toteutukseen ?
Muistioperaationa on nopeampi, mutta tietyn kohdan etsiminen muuttuu samalla hitaammaksi.
Onkohan kukaan keksinyt hybriditietorakennetta, jolla saataisiin taulukon ja "linked LIST" -ratkaisujen parhaat puolety yhdistettyä ? - Anonyymi
Anonyymi kirjoitti:
Aivan riippumatta siitä, miten sen käytännössä toteutat (itse koodaten vai muiden palikoilla leikkien), algoritmi on se, millä on väliä. Jos käsittelet miljoonan rivin datan O(n^2)-algoritmilla, se vie (noin) sata tuhatta kertaa kauemmin kuin O(n*log(n))-algoritmilla.
"Jos käsittelet miljoonan rivin datan O(n^2)-algoritmilla, se vie (noin) sata tuhatta kertaa kauemmin kuin O(n*log(n))-algoritmilla."
Peraatetasolla varmaan ihan totta.
Käytännön huomioina silti:
1. ONKO tuo log(n) millainen logaritmi? Siis 10-kantainen, 2-kantainen vai ns. luonnollinen logaritmi, jossa kantalukuna on ns. neperin luku, jota merkitään yleensä symbolilla e ?
2. QuickSort -algoritmia monet pitävät nopeana.
Mutta onko kyseinen algoritmi kuitenkaan se paras (ja jos on, onko siitä useita erilaisia toteutuksia, jotka eroavat huomattavasti nopeudeltaan) ?
2a) omia kokemuksia:
QuickSort -algoritmi on suhteellisen nopea, jos lajiteltavia alkioita on enintään 100.000 (sata tuhatta). Tätä suuremmilla määrillä QäuickSort -algoritmi voi osoittautua yllätt
vän hitaaksi !
2b) Netistä luettua: QuickSort -algoritmi on erityisen hidas silloin, jos lähtöaineisto on jo ennestään melkein lajiteltu, mutta siellä on muutamia yksittäisiä alkioita, jotka ovat väärässä järjestyksessä.
Voi hyvin olla, että USEIMMISSA tapauksissa QuickSort -algoritmi on nopein vaihtoehto.
ENTÄ, jos algoritmit pisteytetään nopeuden mukaan siten, että kullekin algoritmille annetaan lajiteltavaksi sellainen lähtöaineisto, että kukin algoritmi suoriutuu hitaimmalla mahdollisella tavalla?
Eli verrataan kutakin algoritmia vertaillaan nimenomaan kyseiselle algoritmille omin aisen ns. "worst case" -tapauksen mukaan.
Mikä on tällöin paras algoritmi lajitteluun (oletetaan aineiston kooksi 2 miljoonaa merkkijonoa ja jakaumaksi kullekin algoritmille sellainen, josta on tiedossa, että moinen järjestysjakauma erityisesti hidastaa ko. algoritmia) ? - Anonyymi
Anonyymi kirjoitti:
Keksin että yksi avainsana oli binary search. En ole vielä tarkastanut toimiiko se oikein mutta Delphin TStringList.Find käyttää binääristä hakua kun IndexOf käytti lineaarista. Ensin TStringList.sort niin StringList sortataan (en tiedä miten se konekielitasolla menee kuin 15 merkin jono sortataan). Tämän jälkeen Find funktio palauttaa index-parametrina poistettavan stringin indeksin toisella listilla jotta se voidaan deletoita. Näyttää tunnin algoritmi putoavan muutamaan minuuttiin.
Muita vaihtoehtoja voisi olla kuulemma järjestysluvullinne array. Pitäisi päästä vertailemaan järjestyslukuja, jolloin se olisi yksi komento tai yksi kohta muistissa, ei vertailemaan 15 merkin merkkijonona. Joku hash list, dictionary tai joku. Tehostuisi ehkä vielä suhteessa binäärihakuun.Delphin TStringList:
Tuo binäärihakua käyttävä toimii oikein vain, jos Sorted = True.
Toisaalta esim. insert ja add saattavat olla hitaampia, jos Sorted = True.
Jouduin joskus itse lajittelemaan Delphin TStringList -luokan objektin, jossa oli satojatuhansia merkkijonoja (kukin alkoi kadun nimellä).
Delphin oma Sort -metodi (tai Sorted := True) olivat hyvin hitaita.
Päädyin jakamaan nuo kadun nimet 29 eri TStringList -luokan objektiksi, eli ensimmäiseen tuli "A" -kirjaimella alkavat kadunnimet ja viimeiseen "Ö" -kirjaimella alkavat kadunnimet.
Sitten kullekin TStringList -luokan objektille oma erillinen Sort -metodikutsu.
Tämä tapa oli huomattavasti nopeampi kuin koko pitkän listan lajittelu kerralla. - Anonyymi
Anonyymi kirjoitti:
Poistin ruudulle tulostettan laskurin arvon joka siis käy yhdestä puoleentoistamiljoonaan ja nyt ei tulostu mitään tietoa missä mennään niin ohjelma nopeutui 40 minuutista 4 minuuttiin. Näyttäs toimivan. Mietityttää vaan voiko sillä olla niin iso ero ettei kirjoiteta tuota ruudulle? Vai pakko olla bugi? Mut toistaalta laitoin vain kommenttimerkit yhden rivin eteen.
"voiko sillä olla niin iso ero ettei kirjoiteta tuota ruudulle"
Kyllä voi ja usein onkin !
Jos silti haluat tiedon ruudulle, tee se fiksusti !
esim näin:
Työsäie (periytetty TThread -luokasta)
päivittää muuttujaa, joka ilmaisee joko valmistumisasteen prosentteina, tai sitten (vieläkin nopeampi) läpikäydyn kappalemäärän ja kokonaiskappalemäärä toiseen muuttujaan.
Jos muuttujat on määritelty globaalisti näin:
var
LapiKayty : Longword;
KokonaisKPLMaara : Longword;
niin silloin voi GUI -säikeeseen tehdä vaikkapa formilla olevalla TTimer -komponentilla (Interval = 250) OnTimer -käsittelijän, joka lukee molemmat muuttujat paikallisiin kopioihin näin:
var
A,B : Longword;
PerCent : Double;
S, S1 : String;
begin
A := LapiKayty;
B := KokonaisKPLMaara;
PerCent := LapiKayty * 100.0 / KokonaisKPLMaara;
Str(PerCent:5:1, S1);
S := S1 ' % läpikäyty';
lblProgress.Caption := S;
lblProgress.Repaint;
end;
Teoriassa tuossa kuuluisi lukita nuo muuttujat LapiKayty ja KokonaisKPLMaara (ks. TCriticalSection), mutta koska ne molemmat ovat CPU -rekisterin kokoisia (32 bit) ja ovat muistissa 4:LLÄ jaollisessa osoitteessa, niin tuosta syystä tuo lukitseminen ei ole ihan niin pakollista kuin moni luulee.
Jos haluaa olla ihan 100% varma, ettei eri säikeet aiheuta konfliktia keskenään, niin ks. myös:
InterlockedExchangeAdd ja InterlockedIncrement .
Siis työsäie voisi kasvattaa LapiKayty :
InterlockedIncrement (LapiKayty );
Ja GUI -säie voisi lisätä arvoon LapiKayty vakion nolla, ja napata tuloksen talteen:
InterlockedExchangeAdd (LapiKayty , 0)
JOS tuo viimeinen antaa käännösvirheen, niin korjaa näin:
InterlockedExchangeAdd (@LapiKayty , 0)
Tuolla tavalla hidas näytön päivitys tehdään vain 4 kertaa sekunnissa sensijaan, että se tehtäisiin jokaisen alkion kohdalla (mikä olisi todella hidasta). - Anonyymi
Anonyymi kirjoitti:
"voiko sillä olla niin iso ero ettei kirjoiteta tuota ruudulle"
Kyllä voi ja usein onkin !
Jos silti haluat tiedon ruudulle, tee se fiksusti !
esim näin:
Työsäie (periytetty TThread -luokasta)
päivittää muuttujaa, joka ilmaisee joko valmistumisasteen prosentteina, tai sitten (vieläkin nopeampi) läpikäydyn kappalemäärän ja kokonaiskappalemäärä toiseen muuttujaan.
Jos muuttujat on määritelty globaalisti näin:
var
LapiKayty : Longword;
KokonaisKPLMaara : Longword;
niin silloin voi GUI -säikeeseen tehdä vaikkapa formilla olevalla TTimer -komponentilla (Interval = 250) OnTimer -käsittelijän, joka lukee molemmat muuttujat paikallisiin kopioihin näin:
var
A,B : Longword;
PerCent : Double;
S, S1 : String;
begin
A := LapiKayty;
B := KokonaisKPLMaara;
PerCent := LapiKayty * 100.0 / KokonaisKPLMaara;
Str(PerCent:5:1, S1);
S := S1 ' % läpikäyty';
lblProgress.Caption := S;
lblProgress.Repaint;
end;
Teoriassa tuossa kuuluisi lukita nuo muuttujat LapiKayty ja KokonaisKPLMaara (ks. TCriticalSection), mutta koska ne molemmat ovat CPU -rekisterin kokoisia (32 bit) ja ovat muistissa 4:LLÄ jaollisessa osoitteessa, niin tuosta syystä tuo lukitseminen ei ole ihan niin pakollista kuin moni luulee.
Jos haluaa olla ihan 100% varma, ettei eri säikeet aiheuta konfliktia keskenään, niin ks. myös:
InterlockedExchangeAdd ja InterlockedIncrement .
Siis työsäie voisi kasvattaa LapiKayty :
InterlockedIncrement (LapiKayty );
Ja GUI -säie voisi lisätä arvoon LapiKayty vakion nolla, ja napata tuloksen talteen:
InterlockedExchangeAdd (LapiKayty , 0)
JOS tuo viimeinen antaa käännösvirheen, niin korjaa näin:
InterlockedExchangeAdd (@LapiKayty , 0)
Tuolla tavalla hidas näytön päivitys tehdään vain 4 kertaa sekunnissa sensijaan, että se tehtäisiin jokaisen alkion kohdalla (mikä olisi todella hidasta)."PerCent := LapiKayty * 100.0 / KokonaisKPLMaara;"
siis piti olla:
PerCent := A* 100.0 / B;
Eli käytä laskemiseen paikallisia kopioita muuttujista !
- Anonyymi
Mie oon maailman luokan ammattilainen stringien riisumisessa.
- Anonyymi
Minä olen ollut sitä jo 18 vuotta.
- Anonyymi
Anonyymi kirjoitti:
Minä olen ollut sitä jo 18 vuotta.
Niin, mutta, minä olen paras.
- Anonyymi
Eli siis stringit pois, ja häshimään!
#hashset - Anonyymi
Anonyymi kirjoitti:
Eli siis stringit pois, ja häshimään!
#hashsetThä häh, luulin sitä kirjoitusvirheeksi, perun puheeni, en ole paras, enkä käytä noita ollenkaan.
- Anonyymi
Onko Delphissä valmiina joukko-tietorakennetta? Tee siitä listasta, josta kysytään onko stringi siellä, joukko. Tällöin stringin joukkoon kuuluvuus -testaus on vakioaikaista.
- Anonyymi
"Onko Delphissä valmiina joukko-tietorakennetta"
Kyllä on. ks. avainsana (Reserved Word): Set.
"Tee siitä listasta, josta kysytään onko stringi siellä, joukko."
Delphissä tuo ei onnistu.
Joukko on joukko asioita, joista kukin mahtuu joko tyyppiin BYTE tai muuhun sellaiseen tyyppiin, että SizeOf(tyyppi) = 1.
BYTEn lisäksi sallittuja ovat vakiotyypeistä ShortInt, AnsiChar sekä ne käyttäjän määrittelemät tyypit, joissa S SizeOf(tyyppi) = 1.
Eli vaikka Delphissä on joukot, ne eivät sovellu tapauksiin, joissa joukon alkiot ovat merkkijonoja.
Poikkeus:
Jos eivät ole mielivaltaisia merkkijonoja, vaan kukin merkkijono on vakio, ja noita vakiomerkkijonoja on enintään 256 erilaista, silloin voisi määritellä oman luetellun tyypin, ja laittaa sen eri arvot vastaamaan 256 erilaista vakiomerkkijonoa.
- Anonyymi
String sisällön muuttaminen hashiksi, md5- tai crc32 ja vertailu sillä
- Anonyymi
Mikä vertailu
- Anonyymi
Eikös sinne dictionaryyn voi laittaa avaimeksi merkkijonoa? Joku TDictionary<String, X>, missä tuo X saa olla mitä vaan (vaikka Boolean). Sitten käytät tuota dictionariä vaan niinkuin avainten joukkona. Ja tosiaan, kannattaa tehdä kokonaan uusi lista niistä jätettävistä merkkijonoista.
Disclaimer: en tunne Delphiä ollenkaan, mutta tuon TDictionary:n löysin täältä:
http://docwiki.embarcadero.com/CodeExamples/Sydney/en/Generics_Collections_TDictionary_(Delphi)- Anonyymi
Täällä on tarkemmin kerrottu, kuinka tuon oman joukko-tietorakenteen voi toteuttaa:
https://stackoverflow.com/questions/33529763/is-there-a-hashset-in-delphi/33530037#33530037
Ketjusta on poistettu 0 sääntöjenvastaista viestiä.
Luetuimmat keskustelut
Miehille kysymys
Onko näin, että jos miestä kiinnostaa tarpeeksi niin hän kyllä ottaa vaikka riskin pakeista ja osoittaa sen kiinnostukse1363955- 871939
Olen tosi outo....
Päättelen palstajuttujen perusteella mitä mieltä minun kaipauksen kohde minusta on. Joskus kuvittelen tänne selkeitä tap151821Haluaisin jo
Myöntää nämä tunteet sinulle face to face. En uskalla vain nolata itseäni enää. Enkä pysty elämäänkin näiden kanssa jos541432Kotkalainen Demari Riku Pirinen vangittu Saksassa lapsipornosta
https://www.kymensanomat.fi/paikalliset/8081054 Kotkalainen Demari Riku Pirinen vangittu Saksassa lapsipornon hallussapi531420Ylen uutiset Haapaveden yt:stä.
Olipas kamalaa luettavaa kaupungin irtisanomisista. Työttömiä lisää 10 tai enempikin( Mieluskylän opettajat). Muuttavat1321348VENÄJÄ muuttanut tänään ydinasetroktiinia
Venäjän presidentti Vladimir Putin hyväksyi tiistaina päivitetyn ydinasedoktriinin, kertoo uutistoimisto Reuters. Sen mu981292- 701176
- 691043
Hommaatko kinkkua jouluksi?
Itse tein pakastimeen n. 3Kg:n murekkeen sienillä ja juustokuorrutuksella. Voihan se olla, että jonkun pienen, valmiin k1141033