Autor Zpráva
Dědeček
Profil
Dobrý den,

Mám txt soubor který má takovýto tvar
.Čo znamená pojem „softvérová kríza“?
..nedostatok výkonných počítačov
...neschopnos dostatočne kvalitne a efektívne vyvíja softvér
..nedostatok operačných systémov
..neschopnos softvéru drža krok s hardvérom

.Čo je „softvérové inžinierstvo“?
...systematický prístup k vývoju, prevádzke, údržbe a vyradeniu softvéru
..inžiniersky prístup k programovaniu
..systematický prístup k programovaniu
..modelovanie softvéru

Cílový výstup kterého potřebuji dosáhnout je
Array ( [.Čo znamená pojem „softvérová kríza“? ] => Array ( [1] => ..nedostatok výkonných počítačov [2] => ...neschopnos dostatočne kvalitne a efektívne vyvíja softvér [3] => ..nedostatok operačných systémov [4] => ..neschopnos softvéru drža krok s hardvérom ) [.Čo je „softvérové inžinierstvo“? ] => Array ( [1] => ...systematický prístup k vývoju, prevádzke, údržbe a vyradeniu softvéru [2] => ..inžiniersky prístup k programovaniu [3] => ..systematický prístup k programovaniu [4] => ..modelovanie softvéru ) )

Dosahál jsem ho tímto kódem
<?php    
    $f = fopen ("tmp/text.txt", "r");
    $a= 0;
    while ($line= fgets ($f)) {
            
        if(substr($line, 0, 3)=="…" or substr($line, 0, 2) ==".." or substr($line, 0, 1)=="." and !empty($line))
        {
            $otazky[]=$line;
        }                
        
    }
    fclose ($f);
      
    foreach($otazky as $otazka)
    {
        ++$a;
        
        if(substr($otazka, 0, 3)!="…" and substr($otazka, 0, 2)!=".." and substr($otazka, 0, 1)=="." and !empty($otazka))
        {
            $vysledek[$otazka][1]=$otazky[$a];
            $vysledek[$otazka][2]=$otazky[$a+1];
            $vysledek[$otazka][3]=$otazky[$a+2];
            $vysledek[$otazka][4]=$otazky[$a+3];
        }
    }
    print_r($vysledek);  
?>

Chci se zeptat zdali jde tento kód nějak optimalizovat, jestli není pomalý, nebo jestli to jde jednodušším způsobem. Děkuji mockrát
Nox
Profil
Myslim že "ory" na řádku 6 by měly být celé v závorce

Tak jestli je to pomalé asi vidíte sám, na optimalizování tam toho myslim moc není ... a pokud to nemá sloužit ke zpracování gigantických souborů, tak tím spíš.

Pro lepší čitelnost bych přesunul ř.3 => 13
Dědeček
Profil
Jsou to většinou soubory do 300KB. Pomalé to není. Spíš mě zajímalo jestli se to nedá napsat lépe, protože mě nic lepšího nenapadlo. Díky.
Tori
Profil
Dědeček:
Jedním průchodem např. takto:
$f = fopen("tmp/text.txt", "r");
$zadani = 'Chybí otázka!'; // pokud první řádek nebude otázka
$otazky = array();
$prvniOdpoved = $i = 1; // klíč první odpovědi

while ($line = fgets($f)) {
    $line = trim($line);
    if (!empty($line))    {
        if ($line{1} === '.')    {
            $otazky[$zadani][$i++] = $line;
        } else {
            $zadani = $line;
            $i = $prvniOdpoved;
        }
    }
}
fclose ($f);
Chro
Profil
Dědeček:
Kód před cyklem foreach (fopen, while, fclose) můžeš nahradit tímto:
$otazky = file('tmp/text.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
//načte soubor do pole po řádcích
//ignoruje znak nové řádky na konci každého řádku
//nenačítá prázdné řádky
$a = 0;
Tím odpadá pozdější kontrola (podmínka v cyklu foreach), zda není řádek prázdný.
Borius
Profil
Dědeček:
jestli to jde jednodušším způsobem.
Logaritmus se nechá zeštíhlet na pouhých několik řádků.
~ Pokud použiješ doporučení [#5] Chro – načtení souboru i rozdělení do pole naráz
~ Rozdělení na jednotlivé otázky
~ Vyčlenit první položku jakožto klíč
~ Všechny položky pole zbavit dvou teček

<?php
$otazky=file('tmp/text.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
//Téma, bez počáteční dvojtečky
$klic=substr(array_shift($otazky), 2);
for($i=0;$i<count($otazky); $i++){
    //Odstranit pocáteční tečku
    $otazky[$i]=substr($otazky[$i], 1);
}
//Kompletace pole do potřebného formátu
$otazky[$klic]=$otazky;
?>

Zapomněl jsem na jednu věc – rozdělit na jednotlivé otázky. Např. podle jediné tečky na začátku řádku nebo podle počtu (tzn. čtyř) následujících odpovědí.

Případně by to šlo zjednodušit ještě více, např. použít array_map
Tori
Profil
Dědeček:
Ještě dotaz: proč vlastně tam máte tuhle podmínku if(substr($otazka, 0, 3)!="…" and substr($otazka, 0, 2)!=".." and substr($otazka, 0, 1)==".")? Obsahuje ten soubor i jiná data, než otázky + odpovědi?
Dědeček
Profil
Ještě to upřesním: Jedna tečka = otázka, Dvě tečky = špatná odpověď, Tři tečky = správná odpověd. Teď ještě řeším. Co když někdo napíše ten txt špatně a bude tam více teček nebo tam tečka bude chybět? Jedině zase podmínkami ošetřit co?

Tori:
To tam bylo, protože jsem nevěděl, že se dají ty prázdné řádky odddělit i jinak přímo v file()
Borius:
Děkuju. Ta 2 v array_shift znamená co?
Nox
Profil
Dědeček:
Mj. ten formát je proto, že to tak někdo jiný má a vy to musíte používat, nebo je to něco vlastního? Protože pak by šlo použít třeba JSON a kód by byl prostě
<?php $otazky = json_decode(file_get_contents("text.json"))?>

Nenutím, jen je to podnět k zamyšlení (anebo pro příště)
Borius
Profil
Dědeček:
Ta 2 v array_shift znamená co?
Funkce odstraní první položku z pole a vrátí ji.
Ještě jedna funkce může být ve Tvém případě velice užitečná:
array_chunk($otazky, 5);
Ta rozdělí pole na „menší políčka“, každé s obsahem 5 položek.
Dědeček
Profil
Nox:
Bohužel je to tak daný a já to musím dodržet.
Borius:
No pokud, ale někdo nenapíše, třeba 5 odpovědí, což by tak jako tak nemohl, ale taky dobrá funkce.

Každopádně díky všem za rady :)

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: