String cserélő algoritmus túl lassú / nem túl hatékony
2020-11-26T10:54:23+01:00
2021-01-17T20:32:55+01:00
2022-08-12T00:27:14+02:00
aDaM
Hali! Írtam egy saját PHP-s függvényt, melynek feladata egy tömbként megadott szólista szavait (2-max kb. 5 elemű) egy szintén paraméterként megadott sztringben egymásra cserélni. (Tehát ha van egy szó, mely szerepel a sztringben és a tömbben is, az random módon a tömbben szereplő többi szavak valamelyikére cserélődik a sztringben)
A probléma, hogy ha ezres nagyságrendben iterálódik a program ciklusmagja, mely meghívja ezt a függvényt, nagyon belassul, és a PHP kilép a következő hibaüzenettel "( ! ) Fatal error: Maximum execution time of 120 seconds exceeded in fread.php on line 35"
Amely hibaüzenetben a line értéke változik: vagy a fő for ciklus sorát mutatja a függvény kódjában, vagy a két mb_substr() függvényt használó sorokat hibáztatja a lassúságért


A kérdés, hogy hogyan lehetne gyorsabbá tenni a függvényt, ill ha valakinek alapvetően jobb ötlete van a probléma megoldására, az is jöhet.

A $j változós for ciklus azért kell, mert folyamatosan az összes szót vizsgáljuk és bármelyik ha előfordul, cserélve lesz (kivéve az $actL változó által meghatározottat, azt nem cseréli).
A kód:

function replace($inputtext, &$arrCserelni, $actL){ $outtext = ""; $csereCount = count($arrCserelni); //csere tömb elemeinek száma for($i = 0; $i < mb_strlen($inputtext); $i++) { $cserelt = false; for ($j = 0; $j<$csereCount; $j++){ if (!(($actL-1) == $j)){ $strReplace= $arrCserelni[$j]; $lenReplace= mb_strlen($strReplace); $intReplaceWithIndex = randelement($j, $csereCount); $strReplaceWith = '<span style="color: blue; font-weight:bold;">' . $arrCserelni[$intReplaceWithIndex] . '</span>'; $strSubstr = mb_substr($inputtext, $i, $lenReplace); if ($strSubstr == $strReplace){ $outtext .= $strReplaceWith; if (($j == $csereCount-1) or (($actL == $csereCount) and ($j == $csereCount - 2))) $forchar = 1; else $forchar = 0; //utolsó iterációkor eggyel kevesebb legyen a lenReplace $i += $lenReplace - $forchar; $cserelt = true; } else $cserelt = false; } } if ($cserelt == false) $outtext .= mb_substr($inputtext, $i, 1); } return $outtext; }
Mutasd a teljes hozzászólást!

  • Némi pontosítás - a lecserélt szavakat nem az eredeti sztringbe cseréli vagy írja vissza, hanem egy újat készít a függvény, az $outtext változóba
    Mutasd a teljes hozzászólást!
  • A kódot nem néztem, csak a leírást! Nem lenne gyorsabb, ha
    1 - "szétkapnád" a szöveget (explode?) egy tömbbe
    2 - végig iterálsz (egyszer) az új tömb elemein és összehasonlítod a 2-5 elemű tömbbel (in_array) és találat esetén csere
    3 - összefűzöd az új tömböt ismét egy szöveggé (implode)?
    Mutasd a teljes hozzászólást!
  • Egy minta bemenet szerintem még jó lenne, hogy jobban meg lehessen érteni a működést.

    Egyéb:
    - randelement függvény hogy néz ki?
    - azzal biztos lehetne valamennyit javítani, hogy a mb_strlen($inputtext)-t kivezeted változóba és azt használod a feltételben, így nem fogja annyiszor újra és újra kiszámolni a hosszt
    Mutasd a teljes hozzászólást!
  • Nem mélyedtem bele, de a "gyári" str_replace függvénnyel próbáltad már megoldani?
    Annak ugye van olyan formája is, hogy 2 tömböt kap paraméterül: az első tömb értékeit lecseréli a második tömb megfelelő (=index mentén) értékeire az inputban, és visszatér az új módosított string-gel.
    A második tömb elemei lehetnének ugyanazok, mint az elsőé, de véletlenszerűen megkevere  (pl. shuffle).
    Mutasd a teljes hozzászólást!
  • Hali!

    Mindenekelőtt csatlakozva az előttem szólókhoz, nem ártana (ártott volna) bemenetre is mintákat adni, valamint tényleg hiányzik a randelement() függvény kifejtése. Gyanítom, hogy annyi a szerepe, hogy „önmagára cserélni” ne lehessen.

    Ha jól értettem meg az elvárt működést a kódod alapján, akkor teszteld a következőt. Hevenyészett példaadatokon lefuttatva, akár 20×-os a különbség a te kódodhoz viszonyítva (persze, ez sok dologtól függ):
    function replaceMod(string $text, array &$exchange, int $actL = -1) { $result = ''; $notWordPattern = '/([^\w-]+)/u'; $replaceTemplate = '<span style="color:blue;font-weight:bold">%s</span>'; $text = trim($text); $exchangeCount = count($exchange); $textLength = mb_strlen($text); $splitted = preg_split($notWordPattern, $text, 0, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE); $splittedCount = count($splitted); if ($exchangeCount < 2 || $textLength == 0 || $splittedCount == 0 || preg_match($notWordPattern, $splitted[0])) { return $text; } foreach ($splitted as $idx => $word) { if (!($idx % 2) && ($which = array_search($word, $exchange)) !== false) { $repIdx = -1; while (in_array(($repIdx = rand(0, $exchangeCount - 1)), [$which, $actL])); $splitted[$idx] = sprintf($replaceTemplate, $exchange[$repIdx]); } } $result = implode('', $splitted); return $result; }
    Mutasd a teljes hozzászólást!
  • Hali!

    Sőt, még lehet gyorsítani, ha az előző kódomban a foreach()-et lecseréled for()-ra. Alapesetben a foreach() gyorsabb (ugyanolyan ciklusmag esetén), de jelen példánál a ciklusmagban foreach()-nál összetettebb feltétel-vizsgálat kell, ami – úgy tűnik – többet lassít, mint amennyivel a foreach() önmagában gyorsabb. Tehát:
    … for ($idx = 0; $idx < $splittedCount; $idx += 2) { if (($which = array_search($splitted[$idx], $exchange)) !== false) { $repIdx = -1; while (in_array(($repIdx = rand(0, $exchangeCount - 1)), [$which, $actL])); $splitted[$idx] = sprintf($replaceTemplate, $exchange[$repIdx]); } } …
    Mutasd a teljes hozzászólást!
  • Bemenetre lehetne mondjuk egy tetszőleges természettudományos szöveg, ami megy az $inputtext paraméterbe.
    $arrCserelni tömbbe pedig a cserélendő szinonimák, pl:   array("atom", "részecske", "izotóp"); 

    És akkor ezeket cseréli a szövegben, pl ha az "atom" szó fordul elő, akkor a további kettőre, ha a "részecske" akkor az elsőre vagy a harmadikra, ha az "izotóp" akkor pedig az első kettő valamelyikére.

    Az $actL paraméter - ha nem 0, akkor a megadott sorszámú szót (a tömbből) nem cseréli 

    A randelement függvény rendben van, azt én is néztem emiatt és igen, önmagán kívül más elemek megadására szolgál

    function randelement($actual, $nofelements) //$actual: a tömb hányadik eleménél járunk, $nofelements: az elemek száma { if ($nofelements > 2){ $element = mt_rand(0,$nofelements-1); while ( $element == $actual) $element = mt_rand(0,$nofelements-1); } elseif ($nofelements == 2) $element = 1 - $actual; elseif ($nofelements <= 1) $element = 0; return $element; }
    Mindenkinek köszi egyébként!
    Mutasd a teljes hozzászólást!
  • Az str_replace fv-t asszem azért nem használtam mert itt egyszerre több szót kell vizsgálni és cserélni is. De lehet át lehet arra is alakítani a saját fv-emet, csak én nem tudtam. Itt csak egy tömb van egyébként plusz a bemeneti sztring
    Mutasd a teljes hozzászólást!
  • Igen, látom már, hogy benéztem és nem lesz jó... bocs
    Mutasd a teljes hozzászólást!
  • Szia, itt egy másik verzió.

    A $exchange és a $actL alapján készül egyetlen regexp, ami az összes szóra matchel. Elvileg nem lesz túl nagy, mivel a szólista kicsi. A regexp és egy preg_replace_callback() segítségével végigmegy az szövegen, és a callback függvénnyel cserél.

    A $actL-t úgy értelmeztem, hogy az általa jelölt szót nem cseréli le, de attól még cserével bekerülhet az outputba.

    function replaceMod($text, &$exchange, $actL) { $searchfor = $exchange; if ($actL >= 0) { array_splice($searchfor, $actL, 1); } $qwset = array_map("preg_quote", $searchfor); $qwregexp = "(".implode($qwset, "|").")"; $ecount = count($exchange); return preg_replace_callback($qwregexp, function($m) use($ecount, $exchange) { $idx = rand(0, $ecount-1); return '<span style="color:blue;font-weight:bold">'.$exchange[$idx].'</span>'; }, $text); }
    Mutasd a teljes hozzászólást!
  • Kérdésem lenne ezzel kapcsolatban:

    Az $actL csak akkor mutat valamit ha nagyobb, mint 0.  Tehát az nem tömbindex, hanem sorszám, a tömbindex, melyre vonatkozik az $actL-1. Ha 0 az $actL akkor mindegyiket cseréli. 

    Ezért módosítottam a kódodban az első if feltételében az ($actL >= 0) kifejezést
    erre: ($actL > 0)
    A kérdés, hogy mást mit kellene még módosítani ennek kapcsán a kódodban (ha kell)?
    Amúgy igen, az $actL -1 elemet nem cseréli, de arra cserél.

    Köszi!

    Netangelnek is köszönöm a kódot, bár először ezt tesztelem már le.
    Mutasd a teljes hozzászólást!
  • Csak az array_splice() hívásban szerepel, szóval:

    if ($actL > 0) { array_splice($searchfor, $actL - 1, 1); }
    Mutasd a teljes hozzászólást!
  • OK, még egy gond lenne: úgy látom, önmagára is cserél. Nézegetem én is a kódot, szerintem itt kellene megtiltani ezt valahogy:    $idx = rand(0, $ecount-1);
    Köszi!
    Mutasd a teljes hozzászólást!
  • Így azért bonyolódik. Az $idxmap mappeli vissza a szavakat indexxé. Csere esetén innen kivesszük a talált szó indexét, és ha a véletlen index generálásakor "átlépünk" rajta.

    function replaceMod($text, &$exchange, $actL) { $searchfor = $exchange; if ($actL > 0) { array_splice($searchfor, $actL - 1, 1); } $qwset = array_map("preg_quote", $searchfor); $qwregexp = "(".implode($qwset, "|").")"; $idxmap = []; foreach ($exchange as $i => $w) { $idxmap[$w] = $i; } $ecount = count($exchange); return preg_replace_callback($qwregexp, function($m) use($ecount, $exchange, $idxmap) { $idx = rand(0, $ecount - 2); $midx = $idxmap[$m[0]]; if ($idx >= $midx) { ++$idx; } return '<span style="color:blue;font-weight:bold">'.$exchange[$idx] .'</span>'; }, $text); }
    Mutasd a teljes hozzászólást!
  • Hali!

    Szerintem, lehet ezt egyszerűbben is:
    function replaceMod(string $text, array &$exchange, int $actL = 0) { $searchfor = $exchange; if ($actL > 0) { array_splice($searchfor, $actL - 1, 1); } $qwset = array_map('preg_quote', $searchfor); $qwregexp = '('.implode('|', $qwset).')'; $ecount = count($exchange); return preg_replace_callback($qwregexp, function($m) use($ecount, $exchange) { while (($rep = $exchange[rand(0, $ecount - 1)]) === $m[0]); return "<span style='color:blue;font-weight:bold'>{$rep}</span>"; }, $text); }
    Ez egyébként a korábbi kódod, kicsit módosítva. A következőket változtattam rajta:
    1. Az implode() függvényben megcseréltem a paramétereket. Ugyan még elfogadja azt általad megadott sorrendben is, de 7.4-től kezdve elavult státuszban van (és így várható, hogy valamelyik verzióban a jövőben meg is szüntetik ezt a fajta megadási módot).
    2. A preg_replace_callback() függvény callback-jében egyből a csere-szöveget választom ki, amit azonnal hasonlítok is a lecserélni kívánt szövegre, így elkerülve az önmagára cserét.

    aDaM: Mi a pontos célja a feladatnak, ill. milyen eredményt vársz a lefutástól? Megfelelő, ha az „Egy adott kémiai elem atomjai között különböző tömegszámú atomfajták lehetnek. Ezeket az atomfajtákat hívjuk az illető elem izotópjainak.” bemeneti szöveg és az ['atom', 'részecske', 'izotóp'] bemeneti csere-tömb eredménye az „Egy adott kémiai elem részecskejai között különböző tömegszámú izotópfajták lehetnek. Ezeket az részecskefajtákat hívjuk az illető elem részecskejainak.” Értem úgy, hogy mivel WittnerIsComing megoldása nem teljes szavakon történik, így pl. ragok esetén problémák lehetnek.

    Mutasd a teljes hozzászólást!
  • Megfelelő; igen ezt elfelejtettem kifejteni, hogy a tömb elemei szubsztringekre vonatkoznak. Ha teljes szót akarok cserélni, akkor szóközt teszek elé és utána (az input tömbbe).
    Kicsit rossz példa volt a részemről a 'atom', 'részecske', 'izotóp' szóhármas.
    Mutasd a teljes hozzászólást!
  • Szia!

    Köszönöm a kiegészítést.

    Utólag nézve szerintem is felesleges bonyolítás volt az index építése, bár én az array_search() használatával egyszerűsítettem volna, rövid $exchange tömbre valószínűleg elfogadható sebességű.

    A szóhatár figyelése tényleg nincs benne (az eredeti kódban nem láttam nyomát), de elvileg egyszerűen hozzáadható:

    $qwregexp = '/\\b('.implode('|', $qwset).')\\b/';
    Mutasd a teljes hozzászólást!
  • Hali!

    Megfelelő; igen ezt elfelejtettem kifejteni, hogy a tömb elemei szubsztringekre vonatkoznak.

    OK, értem. Akkor semmi gond, mintha nem is kérdeztem volna.

    Ha teljes szót akarok cserélni, akkor szóközt teszek elé és utána (az input tömbbe).

    Ha ilyenre lesz szükséged, akkor azt majd még gondold át, mert – persze, függően az bemeneti szöveg(-jelleg)től – egyáltalán nem biztos, hogy megfelelő lesz (nem feltétlenül csak szóközök választhatják el egymástól a szavakat).

    Mutasd a teljes hozzászólást!
  • Hali!

    A szóhatár figyelése tényleg nincs benne (az eredeti kódban nem láttam nyomát), de elvileg egyszerűen hozzáadható:

    Ugyan már nincs jelentősége, mivel kiderült, hogy nem teljes szavakra kell elvégezni a feladatot, de ha már felmerült, akkor javasolnék a reguláris kifejezéshez is egy kis módosítást:
    $qwregexp = '/\b(?:'.implode('|', $qwset).')\b/u';
    A módosító miatt így jó lesz UTF-8 szövegre is, valamint a nem gyűjtő csoportosítás (mivel nincs rá szükség) további minimális gyorsítást eredményez(het). De ez már tényleg csak „kekeckedés”.

    Mutasd a teljes hozzászólást!
  • Ha ilyenre lesz szükséged, akkor azt majd még gondold át, mert – persze, függően az bemeneti szöveg(-jelleg)től – egyáltalán nem biztos, hogy megfelelő lesz (nem feltétlenül csak szóközök választhatják el egymástól a szavakat). 

    Igen, ez világos. Erre van megoldás, pl. ha mondatvégi a szó, akkor a ponttal a végén együtt adjuk meg.

    Viszont lenne egy kérésem (akár tőled, akár WittnerIsComing-tól ha nem kérek sokat, vagy nem nagyon off meg ilyenek):
    Az az algoritmusokat módosítanátok úgy, hogy a bemeneti szövegben lévő idézőjelek illetve zárójelek közti szöveget ne figyelje, abban ne cseréljen, csak menjen át a kimenetbe változatlanul. Én is nézegetem a kódjaitokat csak sajnos sok minden nem ismert számomra bennük. :(
    Előre is kösz!
    Mutasd a teljes hozzászólást!
  • Netangel változatát bővítve ilyesmi lenne:

    function replaceMod($text, &$exchange, $actL) { $searchfor = $exchange; if ($actL > 0) { array_splice($searchfor, $actL - 1, 1); } $qwset = array_map('preg_quote', $searchfor); $qwregexp = '/(\\b|[\'"(])('.implode('|', $qwset).')([\'")]|\\b)/u'; $ecount = count($exchange); return preg_replace_callback($qwregexp, function($m) use($ecount, $exchange) { if (strlen($m[1]) > 0 && strpos('\'"(', $m[1]) !== FALSE || strlen($m[3]) > 0 && strpos('\'")', $m[3]) !== FALSE ) { return $m[0]; } while (($rep = $exchange[rand(0, $ecount - 1)]) === $m[2]); return "{$m[1]}<span style='color:blue;font-weight:bold'>{$rep}</span>{$m[3]}"; }, $text); }
    Bonyolódott a regexp: két külön csoport van a szószéleken, ezek matchelnek a szóhatárra és a nem kívánatos határolókra. A cserélő callbackban csak akkor végzünk valódi cserét, ha a határoló nélküli kifejezést találta meg.

    Még lehet rajta javítani, pl. nem figyeli, hogy a határolók szimmetrikusak legyenek, de ez egy életszerű inputban elvileg nem fordul elő úgysem.

    Így viszont nem használhatsz szóközt az $exchange szavai végén, rá kell bíznod magad a kereső kifejezésre.
    Mutasd a teljes hozzászólást!
  • Hali!

    … pl. nem figyeli, hogy a határolók szimmetrikusak legyenek, de ez egy életszerű inputban elvileg nem fordul elő úgysem.

    Tök lazán előfordulhat. De akár „legitim” is lehet (önmagában álló idézőjel, idézőjelek között újabb idézőjel). Zárójeleknél még bonyolultabb, mivel akár egymásba ágyazott, többszintű zárójelezés is lehet. Habár első blikkre jónak tűnhet, ha „mohó” reguláris-kifejezésmintát használsz (ezzel nagyjából kilőheted az egymásban lévő eseteket), de ez meg akkor okoz galibát, ha nem egymásban vannak az idézőjelek/zárójelek, hanem több szövegrész van külön idézőjelezve/zárójelezve.

    Az ilyen feldolgozás messze túlmutat a reguláris kifejezések témakörén. Nagyon leszűkített, pontosan specifikált és – ami a legfontosabb – megbízható bemenetek esetén még csak-csak elfogadható eredményre vezető megoldást lehet alkotni, de ilyen feladatokra inkább pl. tokenizálás lehet a célravezetőbb.

    aDaM: Szupertitkos, hogy pontosan mit/milyen szöveget szeretnél így feldolgozni?

    Mutasd a teljes hozzászólást!
  • Szia!

    Itt szerintem egyszerűbb a helyzet,  a pl. az egymásba ágyazott zárójelezés nem fog bekavarni. Egy lehetséges generált regexp pl.:

    /(\\b|[\'"(])(aaa|bbb)([\'")]|\\b)/u
    Ez csak a közvetlenül a szavak melletti határolókat fogja meg, tehát ((aaa)) esetén csak az (aaa)-t. Amit elszúr, hogy matchel ezekre is: "aaa', 'aaa), de ezek a callback-en belül kezelhetőek (csak lusta voltam beleírni), illetve "normális" szövegben úgyis van szóköz a " vagy ' megfelelő oldalán.

    Ha arra gondolsz, hogy pl. az (ccc aaa ddd)-t nem ismeri fel, mint zárójeles aaa-t, nos, így van. Erre tényleg nem jó.

    aDaM kérdésére: az "akármi " már nem használható, mert akkor az "(akármi )" lesz a zárójeles változat, ami nyilván nem jó. A szóhatárra kénytelen vagy matchelni (környezet figyelése miatt), vagy át kell írni az algoritmust.
    Mutasd a teljes hozzászólást!
  • Említetted a tokenezést, tulajdonképpen meg lehet csinálni a mostani rutin átalakításával:

    function replaceMod($text, &$exchange, $actL) { $ca=[]; $searchfor = $exchange; if ($actL > 0) { array_splice($searchfor, $actL - 1, 1); } $qwset = array_map('preg_quote', $searchfor); $qwregexp = '/('.implode('|', $qwset).'|[\'"()])/u'; $ecount = count($exchange); return preg_replace_callback($qwregexp, function($m) use($ecount, &$exchange, &$ca) { if (strlen($m[0]) === 1 && strpos('\'"()', $m[0]) !== FALSE) { $cur = $m[0]; $last = count($ca) > 0 ? $ca[count($ca) - 1] : ''; if (($last === '\'' || $last === '"') && $last === $cur || $last === '(' && $cur === ')') { array_pop($ca); } else { array_push($ca, $cur); } return $m[0]; } if (count($ca) > 0) { return $m[0]; } while (($rep = $exchange[rand(0, $ecount - 1)]) === $m[0]); return "<span style='color:blue;font-weight:bold'>{$rep}</span>"; }, $text); }

    A $ca egy verem, amiven számon tartjuk, hol, milyen mélyen vagyunk az egyes határolókban. Ha határolón belül vagyunk, akkor nem cserélünk.

    Így ráadásul nem kell szóhatárt figyelni, szóval használható aDaM "akármi." keresési megoldása.
    Mutasd a teljes hozzászólást!
  •  az "akármi " már nem használható, mert akkor az "(akármi )"

    Hogy érted? A megadott szavak közt a tömbben nem lesznek zárójeles szavak vagy szövegrészek. A rendes szövegben pedig a zárójeles részszövegeket egyszerűen figyelmen kívül hagyja a zárójelekkel együtt, azon belül nem cserél. Ugyanígy az idézőjeles szövegrészeknél.

    Ha a tömbben "akármi." van megadva (többek között), akkor a szövegben is csak az "akármi." részszöveget cseréli. Feltéve ha nem zárójelben vagy idéző jelek közt van,
    Amúgy a zárójelezés 2 szintnél nem nagyon lesz több.
    Mutasd a teljes hozzászólást!
  • Az utolsó változat már úgy dolgozik, ahogy írod (azt hiszem :). Az előzőre ez még nem volt igaz.
    Mutasd a teljes hozzászólást!
  • Hali!

    Készítettem egy olyat, ami többnyire (értsd: érdekes eredményre vezet, ha az egymásba ágyazott zárójelek nincsenek egyensúlyban, ill. az idézőjelek/aposztrófok nincsenek párban) megfelel a kívánalmaidnak. Mind a zárójeleket (egymásba ágyazottakat is, bármennyi szintig), mind az idézőjelet/aposztrófot kezeli (azaz, az ezek közötti szövegrészben nincs csere).
    function replaceMod(string $text, array &$exchange, int $actL = -1) { $searchFor = $exchange; if ($actL > 0) { array_splice($searchFor, $actL - 1, 1); } $replacePattern = '/(\((?>[^()]|(?1))*\))(*SKIP)(*FAIL)|([\'\"])[^\2]*?\2(*SKIP)(*FAIL)|'; $replacePattern .= '(?:'.implode('|', array_map('preg_quote', $searchFor)).')/su'; $count = count($exchange); return preg_replace_callback($replacePattern, function($m) use ($count, $exchange) { while (($rep = $exchange[rand(0, $count - 1)]) == $m[0]); return "<span style='color:blue;font-weight:bold'>{$rep}</span>"; }, $text); } $text = 'egy kettő egy (kettő egy kettő) egy kettő "egy" kettő "egy kettő" egy (kettő egy kettő egy (kettő (egy) kettő egy) kettő) egy "kettő \'egy\' kettő" egy kettő'; $exchange = ['egy', 'kettő']; echo replaceMod($text, $exchange);
    Eredménye (cseréket aláhúzással jelöltem):
    kettő egy kettő (kettő egy kettő) kettő egy "egy" egy "egy kettő" kettő (kettő egy kettő egy (kettő (egy) kettő egy) kettő) kettő "kettő 'egy' kettő" kettő egy
    Továbbra sem árulod el, hogy pontosan mire kell ez neked?

    Mutasd a teljes hozzászólást!
  • Hali! Köszi, a zárójelesen átmegy, bár úgy látom kimaradt a randomizálásos elemválasztás rész. Azt még vissza kéne valahogy csempészni (meg amik eddig már meg voltak) ha nem gond.
    WittnerIsComing legutolsó programja sem randomizál ha jól látom. (Vagy vmi szerverbeállítást nagyon elbénáztam.)

    Annyi a lényeg, hogy a szinonimákkal gazdagítja a program az adott szöveget. 

    Köszi! :)
    Mutasd a teljes hozzászólást!
  • Hali!

    … bár úgy látom kimaradt a randomizálásos elemválasztás rész.

    Szerintem rosszul látod. A példámban azért áll mind a bemeneti szöveg, mind a cserélhető lehetőségek csak az „egy” és „kettő” szavakból, hogy egyértelműen látszódjon a zárójelek és idézőjelek/aposztrófok közötti cserék hiánya. Mivel csak két alternatíva van, és ugyanezekből áll a szöveg is, így az igényeidnek megfelelő algoritmus megvalósítása nem mást csinál, mint a két szót kicseréli (hiszen feltétel volt, hogy önmagára nem cserélheti). De próbáld ki pl. az ['egy', 'kettő', 'három', 'négy', 'öt'] csere-tömbre.

    Annyi a lényeg, hogy a szinonimákkal gazdagítja a program az adott szöveget.

    És figyelsz mindenre? Megfelelő határozott névelő, ragok, toldalékok (megfelelő hangnemű) alkalmazására?

    Mutasd a teljes hozzászólást!
abcd