Matematické Fórum

Nevíte-li si rady s jakýmkoliv matematickým problémem, toto místo je pro vás jako dělané.

Nástěnka
22. 8. 2021 (L) Přecházíme zpět na doménu forum.matweb.cz!
04.11.2016 (Jel.) Čtete, prosím, před vložení dotazu, děkuji!
23.10.2013 (Jel.) Zkuste před zadáním dotazu použít některý z online-nástrojů, konzultovat použití můžete v sekci CAS.

Nejste přihlášen(a). Přihlásit

#1 18. 05. 2016 16:18

cetis
Příspěvky: 53
Škola: MFF UK
Pozice: student
Reputace:   
 

Abeceda

prosím Vás, potřeboval bych poradit s touto úlohou.
Zatím jsem akorát vyřešil vstup tak, že jsem si jednotlivy znaky tabulky ulozil do dvourozmernyho pole, ale úplně nevím jak dál. Někdo mi poradil, že by bylo dobrý na to použít dijsktrův algoritmus, ale úplně si nedokážu představit implementaci na to pole.

Za jakoukoliv radu předem děkuji.


V některých elektronických zařízeních se texty zadávají pomocí tabulky písmen.
V tabulce se pohybuje kurzor (výchozí poloha v levém horním rohu, pohyb tlačítky šipek nahoru, dolů, doleva a doprava) a klávesou Enter volíme zapsání znaku.


Pokud například tabulka vypadá takto:

      ABCDEFGH
      IJKLMNOP
      QRSTUVWX
      YZ

, text "AHOJ" napíšeme stisky tlačítek (jedno z možných řešení)

      Enter
      doprava
      doprava
      doprava
      doprava
      doprava
      doprava
      doprava
      Enter
      doleva
      dolů
      Enter
      doleva
      doleva
      doleva
      doleva
      doleva
      Enter

Napište program, který pro danou tabulku (může obsahovat malá i velká písmena) a text (může obsahovat i jiné znaky) určí a vytiskne minimální počet stisků tlačítek potřebných pro napsání textu.

Pozor: Písmena v tabulce se mohou opakovat!

Vstup obsahuje čísla udávající šířku a výšku tabulky (každé na samostatném řádku), dále na jednom řádku obsah tabulky (čtené po řádkách) a nakonec text, který má být napsán. Znaky textu, které nejsou v tabulce, budou ignorovány.

Příklad:
Vstup:
   3
   3
   ABCBFECDF
   ABCDEFA
Výstup:
   15
Komentář:
Tabulka v tomto příkladu má podobu

   ABC
   BFE
   CDF

, text ABCDEFA lze napsat více způsoby, 15 stisků je délka nejkratšího z nich.

Offline

 

#2 20. 05. 2016 18:10

Formol
Místo: Praha
Příspěvky: 782
Pozice: krotitel mikroskopů (UHIEM 1. LF UK)
Reputace:   42 
 

Re: Abeceda

Ahoj,
rozděl si problém, to často pomáhá. Vlastně jde o opakované hledání nejkratší cesty právě dvojice znaků, cesta při hledání neovlivní cestu při hledání jiné dvojice. To znamená, že když budeš hledat např. slovo "VUZ" a začínáš vlevo nahoře, tedy na znaku "A", hledáš vlastně postupně nejmenší cestu "AV", "VU" a "UZ". Takže ti jde jen o to, abys našel nejmenší cestu dvou znaků.

Jistě si můžeš klávesnici nějak reprezentovat grafem a pak na to napálit Dijskrův algoritmus, ale to je trochu kanón na vrabce. Místo toho se můžeš zamyslet nad strukturou matice:
1. Znaky "Y" a "Z" jako výchozí si ošetři zvlášť třeba tak, že pokud půjde o cestu "YZ" (např. ve slově "kyz") nebo "ZY" (např. ve slově "zygota"), vyřeší to první podmínka. V opačném případě dáš jeden krok "nahoru" a "Y" přejde v "Q" a "Z" přejde v "R".

2. Ostatní znaky máš v tabukce 3x8, srovnané podle abecedy. Tady už můžeš celkem snadno operovat s tím, že znaky jsou v obvyklých jazycích ordinální typ. Když si klávesnici přepíšeš po pořadových číslech, dostaneš:

Code:

01 02 03 04 05 06 07 08
09 10 11 12 13 14 15 16
17 18 19 20 21 22 23 24

Většina jazyků má operace celočíselného dělení a zbytku po celočíselném dělení, tím už snadno určíš souřadnice znaku. A protože jsou to čtverečky, můžeš si souřadnice dvou znaků spojit po "L", tj. nejdřív pohybem nahoru/dolů vyrovnáš řádek, potom doprava/doleva vyrovnáš sloupec.


Доктор сказал «в морг» — значит в морг!

Offline

 

#3 20. 05. 2016 19:27

Stýv
Vrchní cenzor
Příspěvky: 5692
Reputace:   215 
Web
 

Re: Abeceda

↑ Formol: myslím, že je to trochu složitější, jelikož se písmena v tabulce můžou opakovat

Offline

 

#4 23. 05. 2016 19:02

Formol
Místo: Praha
Příspěvky: 782
Pozice: krotitel mikroskopů (UHIEM 1. LF UK)
Reputace:   42 
 

Re: Abeceda

↑ Stýv:
Díky, máš pravdu, tohle jsem tak nějak přehlédl :-(

↑ cetis:
Pokud se mohou písmena, je to trochu složitěší v tom, že tabulka není tak hezky učesaná. Jedno z možných řešení je tabulku reprezentovat nějakou hezkou dynamickou strukturou, která bude udržovat o každém písmeni informaci o jeho souřadnicích v tabulce. Tím, že se může opakovat, můžeš dostat i několik výsledků, z nich musíš uvažovat vlastně všechny, protože výběr aktuálně nejlepší dráhy může vést k horšímu výsledku o znak později.

První nápad za situace odpovídající zadání je ten, že si postupně sestrojíš všechny možné průchody klávesnicí a vybereš ten nejlepší. Např. budeš mít tabulku písmen se souřadnicemi:
A->[1,1]->[3,3]
B->[1,2]->[2,1]
C->[2,2]
(A a B je 2x)

Dostaneš sekvenci "ACAB", kterou si přepíšeš na sekvence uspořádaných dvojic
[1,1]->[2,2]->[1,1]->[1,2]
[1,1]->[2,2]->[3,3]->[1,2]
[3,3]->[2,2]->[1,1]->[1,2]
[3,3]->[2,2]->[3,3]->[1,2]
[1,1]->[2,2]->[1,1]->[2,1]
[1,1]->[2,2]->[3,3]->[2,1]
[3,3]->[2,2]->[1,1]->[2,1]
[3,3]->[2,2]->[3,3]->[2,1]

A z nich vybereš prostě tu nejkratší lomenou čáru měřeno v "taxikářské" míře.
Rozmysli si, jestli jde poslední řádek ošetřit tak, že natvrdo skočíš o řádek nahoru.

Přímočará programová realizace je taková, že si budeš do fronty sypat jednotlivé body, při každém větvení (více kláves se stejným písmenem) prostě frontu zduplikuješ a na konci dostaneš fronty odpovídající všem možným kombinacím. To je ale docela plýtvání pamětí. První nápad na optimalizaci je ten, že budeš hledat nejkratší cestu po částech, vždy jen do nejbližšího písmena, které je na klávesnici pouze jednou. (je třeba ošetřit poslední znak). Nebo se můžeš zamyslet víc než já a popřemýšlet o možnostech rekurze...


Доктор сказал «в морг» — значит в морг!

Offline

 

Zápatí

Powered by PunBB
© Copyright 2002–2005 Rickard Andersson