ITnetwork Flashka zdarma C a C++ týden
Akce! Pouze tento týden sleva až 80 % na kurzy C++. Lze kombinovat s akcí 50 % bodů navíc na prémiový obsah!
Brno? Vypsali jsme pro vás nové termíny školení Základů programování a OOP v Brně!

Lekce 9 - Textové řetězce v Javě do třetice - Split a join

Unicorn College Tento obsah je dostupný zdarma v rámci projektu IT lidem.
Vydávání, hosting a aktualizace umožňují jeho sponzoři.

V minulé lekci, Textové řetězce v Javě podruhé - práce s jednotlivými znaky, jsme si ukázali, že String je vlastně pole znaků. Dnes si vysvětlíme další metody na řetězci, které jsem vám záměrně zatajil, protože jsme nevěděli, že String je vlastně pole :)

Když si vytvoříme libovolnou proměnnou a napíšeme za ni poté tečku, zobrazí nám NetBeans nabídku všech metod a vlastností (a také proměnných, ale k tomu se dostaneme až u objektů), které na ni můžeme volat. Zkusme si to:

Metody na textovém řetězci string v NetBeans

Tu samou nabídku lze vyvolat také stiskem CTRL + Mezerník v případě, že kurzor umístíme na tečku. Samozřejmě to platí pro všechny proměnné i třídy a budeme toho využívat stále častěji. Metody jsou řazené abecedně a můžeme jimi listovat pomocí kurzorových šipek. NetBeans nám zobrazuje popis metod (co dělají) a jaké vyžadují parametry.

Řekněme si o následujících metodách a ukažme si je na jednoduchých příkladech:

Další metody na řetězci

Substring()

Vrátí podřetězec od dané počáteční pozice do dané koncové pozice.

System.out.println("Kdo se směje naposled, ten je admin.".substring(13, 21));

Výstup:

Konzolová aplikace
naposled

CompareTo()

Umožňuje porovnat dva řetězce podle abecedy. Vrací -1 pokud je první řetězec před řetězcem v parametru, 0 pokud jsou stejné a 1 pokud je za ním:

System.out.println("akát".compareTo("blýskavice"));

Výstup:

Konzolová aplikace
-1

Pojďme se nyní podívat na další metodu na Stringu, která je opravdu velmi užitečná.

Split() a join()

Z předchozího tutoriálu víme, že parsování řetězce po znaku může být někdy docela složité a to jsme dělali poměrně jednoduchý příklad. S řetězci se samozřejmě budeme setkávat stále, a to jak na vstupu od uživatele (např. z konzole nebo z polí v okenních aplikacích), tak v souborech TXT a XML. Velmi často máme zadán jeden delší String (řádka souboru nebo řádka konzole), ve kterém je více hodnot, oddělených tzv. separátory, např. čárkou. V tomto případě hovoříme o formátu CSV (Comma-Separated Values, tedy hodnoty oddělené čárkou). Abychom si byli jisti, že víme, o čem hovoříme, ukažme si nějaké ukázkové řetězce:

Jan,Novák,Dlouhá 10,Praha 3,130 00
.. ... .-.. .- -. -.. ... --- ..-. -
(1,2,3;4,5,6;7,8,9)

První řetězec je očividně nějaký uživatel, takto bychom mohli např. realizovat uložení uživatelů do CSV souboru, každý na jeden řádek.
Druhý řetězec jsou znaky Morseovy abecedy, separátor (oddělovač) je zde mezera.
Třetí řetězec je matice o 3 sloupcích a 3 řádcích. Oddělovač sloupců je čárka, řádků středník

Na stringu můžeme volat metodu split(), která bere jako parametr separátor. Následně původní řetězec rozdělí podle separátorů na pole podřetězců, které vrátí. To nám velmi ulehčí práci při rozdělování hodnot v řetězci.

Metoda join() se volá přímo na typu String a umožňuje nám naopak pole podřetězců spojit oddělovačem do jediného řetězce, parametry jsou oddělovač a pole. Výstupem metody je výsledný řetězec.

Jelikož neumíme tvořit objekty (uživatele) a ani pracovat s vícerozměrnými poli (matice), zkusíme si naprogramovat dekodér zpráv z Morseovy abecedy.

Dekodér Morseovy abecedy

Pojďme si opět připravit strukturu programu. Budeme potřebovat 2 řetězce se zprávou, jeden se zprávou v Morseově abecedě, druhý zatím prázdný, do kterého budeme ukládat výsledek našeho snažení. Dále budeme jako v případě samohlásek potřebovat nějaký vzor písmen. K písmenům samozřejmě vzor jejich znaku v morzeovce. Písmena můžeme opět uložit do pouhého Stringu, protože mají jen jeden znak. Znaky Morseovy abecedy mají již znaků více, ty musíme dát do pole. Struktura našeho programu by nyní mohla vypadat následovně:

// řetězec, který chceme dekódovat
String s = ".. - -. . - .-- --- .-. -.-";
System.out.printf("Původní zpráva: %s\n", s);
// řetězec s dekódovanou zprávou
String zprava = "";

// vzorová pole
String abecedniZnaky = "abcdefghijklmnopqrstuvwxyz";
String[] morseovyZnaky = {".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....",
"..", ".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-",
"...-", ".--", "-..-", "-.--", "--.."};

Můžete si potom přidat další znaky jako čísla a interpunkční znaménka, my je zde vynecháme. Nyní si řetězec s rozbijeme metodou split() na pole podřetězců, obsahujících jednotlivé znaky morzeovky. Splitovat budeme podle znaku mezery. Pole následně proiterujeme cyklem foreach:

// rozbití řetězce na znaky morzeovky
String[] znaky = s.split(" ");

// iterace znaků morzeovky
for (String morseuvZnak : znaky) {

}

Ideálně bychom se měli nějak vypořádat s případy, kde uživatel zadá např. více mezer mezi znaky (to uživatelé rádi dělají). Split() poté vytvoří o jeden řetězec v poli více, který bude prázdný. Ten bychom měli poté v cyklu detekovat a ignorovat, my se s tím v tutoriálu nebudeme zabývat.

V cyklu se pokusíme najít aktuálně čtený znak morzeovky v poli morseovyZnaky. Bude nás zajímat jeho index, protože když se podíváme na ten samý index v poli abecedniZnaky, bude tam odpovídající písmeno. To je samozřejmě z toho důvodu, že jak pole tak řetězec obsahují stejné znaky, seřazené dle abecedy. Umístěme do těla cyklu následující kód:

char abecedniZnak = '?';

int index = -1;
for (int i = 0; i < morseovyZnaky.length; i++) {
    if (morseovyZnaky[i].equals(morseuvZnak))
        index = i;
}

if (index >= 0) { // znak nalezen
    abecedniZnak = abecedniZnaky.charAt(index);
}
zprava += abecedniZnak;

Kód nejprve do abecedního znaku uloží '?', protože se může stát, že znak v naší sadě nemáme. Následně se pokusíme zjistit jeho index. Pole v Javě bohužel nemá metodu indexOf() a zatím nechci zabíhat do složitějších datových struktur. Napíšeme si tedy vyhledání Stringu v poli sami, bude to docela jednoduché.

Nejprve nastavíme index na -1, protože nevíme, jestli pole daný String (morzeův znak) obsahuje. Následně pole projedeme cyklem a budeme kontrolovat jednotlivé Stringy s naším stringem (znakem). Již víme, že musíme k porovnání dvou řetězců použít metodu equals(). Pokud řetězce souhlasí, uložíme si aktuální index.

Pokud jsme znak našli (index >= 0), dosadíme do abecedniZnak znak z abecedních znaků pod tímto indexem. Nakonec znak připojíme ke zprávě. Operátor += nahrazuje zprava = zprava + abecedniZnak.

Závěrem samozřejmě zprávu vypíšeme:

System.out.printf("Dekódovaná zpráva: %s\n", zprava);

Konzolová aplikace
Původní zpráva: .. - -. . - .-- --- .-. -.-
Dekódovaná zpráva: itnetwork

Hotovo! Za úkol máte si naprogramovat program opačný, který naopak zakóduje řetězec do morzeovky, kód bude velmi podobný. Se split() a join() se potkáme během Java kurzu ještě několikrát.

Speciální znaky a escapování

Textový řetězec může obsahovat speciální znaky, které jsou předsazené zpětným lomítkem "\". Je to zejména znak \n, který kdekoli v textu způsobí odřádkování a poté \t, kde se jedná o tabulátor. Pojďme si to vyzkoušet:

System.out.println("První řádka\nDruhá řádka");

Znak "\" označuje nějakou speciální sekvenci znaků v řetězci a je dále využíván např. k psaní unicode znaku jako "\uxxxx", kde xxxx je kód znaku.

Problém může nastat ve chvíli, když chceme napsat samotné "\", musíme ho tzv. odescapovat:

System.out.println("Toto je zpětné lomítko: \\");

Stejným způsobem můžeme odescapovat např. uvozovku tak, aby ji Java nechápala jako konec řetězce:

System.out.println("Toto je uvozovka: \"");

Vstupy z konzole a polí v okenních aplikacích se samozřejmě escapují sami, aby uživatel nemohl zadat \n a podobně. V kódu to má programátor povoleno a musí na to myslet.

Tímto jsme v podstatě zakončili kurz se základní strukturou jazyka Java. V příštích lekcích si uvedeme vícerozměrná pole a matematické operace. Ze základních konstrukcí jazyka vás tu ale již nic nepřekvapí :) V podstatě byste již klidně mohli jít i na objekty, doporučují ale zbylé tutoriály ještě alespoň projet, jedná se přeci jen stále o základní znalosti, které byste měli mít. V příští lekci, Vícerozměrná pole v Javě, se tedy uvidíme u vícerozměrných polí.


 

Stáhnout

Staženo 822x (20.2 kB)
Aplikace je včetně zdrojových kódů v jazyce java

 

 

Článek pro vás napsal David Čápka
Avatar
Jak se ti líbí článek?
20 hlasů
Autor pracuje jako softwarový architekt a pedagog na projektu ITnetwork.cz (a jeho zahraničních verzích). Velmi si váží svobody podnikání v naší zemi a věří, že když se člověk neštítí práce, tak dokáže úplně cokoli.
Unicorn College Autor sítě se informační technologie naučil na Unicorn College - prestižní soukromé vysoké škole IT a ekonomie.
Předchozí článek
Textové řetězce v Javě podruhé - práce s jednotlivými znaky
Všechny články v sekci
Základní konstrukce jazyka Java
Miniatura
Následující článek
Cvičení k 9. lekci Javy
Aktivity (12)

 

 

Komentáře

Avatar
petr.chatar.anton:15.10.2013 16:41

Zdar chlapi,
mám další začátečnickou otázku a to ke kódování. Při procvičování jsem narazil na to, že program spuštěný ve Windows příkazovém řádku zobrazuje špatně češtinu. Tak jsem zkoušel takto:

public static void main(String[] args) {
Scanner sc = new Scanner(System.in, "Windows-1250");
System.out.println("Ahoj blbečku !!!");
System.out.println("Zadej své jméno :");
String text = sc.nextLine();
System.out.println(text);
}

Všechno se vypisuje blbě česky, jen ten String text je správně.
Zkusil jsem v properties projektu nastavit kódování taky na 1250, ale to udělalo tu češtinu ještě horší. Poradíte mi, jak dostat správný český výstup v CMD ? Používám Netbeans 7.3.1.

 
Odpovědět 15.10.2013 16:41
Avatar
Juraj Mlich
Redaktor
Avatar
Odpovídá na petr.chatar.anton
Juraj Mlich:15.10.2013 16:44

Skús kódovanie utf8.

 
Odpovědět  +1 15.10.2013 16:44
Avatar
Ondrca
Redaktor
Avatar
Odpovídá na petr.chatar.anton
Ondrca:15.10.2013 16:50

Přeně jak říká Juraj:

Scanner sc = new Scanner(System.in, "UTF-8");
Odpovědět 15.10.2013 16:50
Zase jsem o něco chytřejší
Avatar
Odpovídá na petr.chatar.anton
petr.chatar.anton:15.10.2013 16:56

Nene, právě že projekt je v UTF-8. To, co jsem načetl Scannerem do proměnné "text" se vypsalo správně. To co vypisuje samotná Java je špatně, viz obrázek.

 
Odpovědět 15.10.2013 16:56
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na petr.chatar.anton
David Čápka:18.10.2013 12:12

Vždy mi fungovalo Windows-1250. Zkus si stáhnout zdrojový kód pod článek, zda ti to půjde.

Odpovědět 18.10.2013 12:12
Jsem moc rád, že jsi na síti, a přeji ti top IT kariéru, ať jako zaměstnanec nebo podnikatel. Máš na to! :)
Avatar
petr.chatar.anton:18.10.2013 13:11

Dobře, stáhnul jsem si a spustil MorzeovkaDeko­der.jar. Ale ta čeština je tam špatně. Zkusil jsem se zeptat pomocí CHCP, ten tvrdí, že kódová stránka je 852. Tak nevím. Přenastavení CHCP 1250 taky nepomůže. Ono to asi moc důležitý není, páč kdo použije konzolovou aplikaci? Spíš mi to štve principielně, proč mi to nejde.

 
Odpovědět 18.10.2013 13:11
Avatar
Honza
Neregistrovaný
Avatar
Honza:4.11.2013 22:30

Dobrý den,

mám následující problém. Poté co vybuidldím projekt v NetBeans a ve složce dis kliknu na mou .jar aplikaci tak se otevře ve WinRARu. Zkoušel jsem nastavic asociaci na javaw.exe ale to nefunguje. V příkazovém řádku lze aplikace spustit příkazem java -jar "název.jar". Nicméně v kontextové nabídce Otevřít pomocí programu... jsem nenašel způsob jak soubor otevírat v javaw.exe s parametrem -jar.

Prosím o radu.

 
Odpovědět 4.11.2013 22:30
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Honza
David Čápka:19.11.2013 12:04

Můžeš zkusit program jarfix, který asociaci obnovuje. Nimcméně konzolovou aplikaci takto stejně nespustíš, to jde jen z konzole.

Odpovědět 19.11.2013 12:04
Jsem moc rád, že jsi na síti, a přeji ti top IT kariéru, ať jako zaměstnanec nebo podnikatel. Máš na to! :)
Avatar
Drezir
Neregistrovaný
Avatar
Drezir:3.3.2014 14:49

zkoušel jsem to trochu zkrátit a vyšlo toto, ale to tvoje je přehlednější. Dobrá práce, díky :)

int index = -1;
int pom = 0;
for (int i = 0; i < morseovyZnaky­.length; i++) {
if (morseovyZnaky[i]­.equals(znaky[pom])) {
index = i;
pom++;
i=-1;
zprava+=abeced­niZnaky.charAt(in­dex);
if (pom==znaky.length)
break;
}
}

 
Odpovědět 3.3.2014 14:49
Avatar
Martin.mak
Člen
Avatar
Martin.mak:27.4.2014 23:09

" Pole v Javě bohužel nemá metodu indexOf()"
Kus kódu z Programu "Morzeovka" (cvičení 9. - 2.)

int pozice = abecedniZnaky.indexOf(zprava.charAt(i));

??? :D

 
Odpovědět 27.4.2014 23:09
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Martin.mak
David Čápka:1.5.2014 9:31

Existuje rozdíl mezi polem a řetězcem.

Odpovědět  +1 1.5.2014 9:31
Jsem moc rád, že jsi na síti, a přeji ti top IT kariéru, ať jako zaměstnanec nebo podnikatel. Máš na to! :)
Avatar
Martin.mak
Člen
Avatar
Martin.mak:1.5.2014 23:47

Aha, hodilo by se doplnit, že řetězce metodu indexOf mají když už jsi to použil v tom kódu u morzeovky :)

 
Odpovědět 1.5.2014 23:47
Avatar
robineki
Člen
Avatar
Odpovídá na David Čápka
robineki:30.12.2014 14:51

Dá se napsat do toho Scanneru i něco jiného než Windows-1250?
Díky,
Robineki

 
Odpovědět 30.12.2014 14:51
Avatar
Tomáš Brůna
Redaktor
Avatar
Tomáš Brůna:8.1.2015 17:09

ahoj je nějaký způsob jak se dá naprogramovat na spuštění třeba prohlížeče hry a dalších programů?

Odpovědět 8.1.2015 17:09
Lepší být šprt než blbec :)
Avatar
Tomáš Brůna
Redaktor
Avatar
Tomáš Brůna:13.1.2015 18:56

ahoj co dělá v podmínce znak %? Děkuji předem Tomáš

Odpovědět 13.1.2015 18:56
Lepší být šprt než blbec :)
Avatar
Contrix
Redaktor
Avatar
Odpovídá na Tomáš Brůna
Contrix:13.1.2015 19:23

Jedná se o zbytek po dělení..třeba if(x % 2 ==0), tak je číslo dělitelné dvěma.

Editováno 13.1.2015 19:23
Odpovědět 13.1.2015 19:23
Jsou zloději, které zákon netrestá, třebaže kradou člověku to nejcennější čas.
Avatar
Vakos
Redaktor
Avatar
Vakos:11.4.2015 17:44

Jde u split nastavit 2 parametry? chtěl bych nastavit mezeru a zároveň /

Odpovědět 11.4.2015 17:44
"Jediný způsob, jak dělat skvělou práci, je milovat to, co děláte. Pokud jste to ještě nenašli, hledejte dál. Ne...
Avatar
Jan Vargovský
Redaktor
Avatar
Odpovídá na Vakos
Jan Vargovský:11.4.2015 17:49

Se koukni jak funguje regex :)

 
Odpovědět 11.4.2015 17:49
Avatar
roman64
Redaktor
Avatar
roman64:29.5.2015 17:35

Dovolím si upozornit na jednu malou nepřesnost u metody SUBSTRING. Druhý parametr není delka (jak bývá obvyklé a lze očekávat), ale index konečného znaku požadovaného sub-řetezce.

Odpovědět  +1 29.5.2015 17:35
Definice šílenství je dělat stejnou věc znovu a znovu a očekávat jiné výsledky.“ Albert Einstein.
Avatar
Odpovídá na roman64
Tomas Hlinovsky:2.12.2015 22:43

já nechápu u toho substringu proc to zleva bere vcetne a zprava jakoby o jedno min..

 
Odpovědět 2.12.2015 22:43
Avatar
Lubor Pešek
Člen
Avatar
Lubor Pešek:3.12.2015 12:32

a jak bys chtěl aby to fungovalo?

Odpovědět 3.12.2015 12:32
Existují dva způsoby, jak vyřešit problém. Za prvé vyhoďte počítač z okna. Za druhé vyhoďte okna z počítače.
Avatar
roman64
Redaktor
Avatar
Odpovídá na Tomas Hlinovsky
roman64:3.12.2015 16:46

Ahoj. Možná tito bude jasnější s touto iterací:

public static void main(String[] args) {
        String retez = "Ahoj jak se máš?";
        int i;
        for (i=0; i<retez.length();i++)
            System.out.println(retez.substring(0,i));
    }
Odpovědět 3.12.2015 16:46
Definice šílenství je dělat stejnou věc znovu a znovu a očekávat jiné výsledky.“ Albert Einstein.
Avatar
Tomáš Kamlar:6.12.2015 16:32

moje verze pro opětovné zakodování zprávy do Moseovy abecedy :)

String zprava2 = "";

       for (char abecedniZnak : zprava.toCharArray())
        {
           int index = -1;
           String znak = " ";
            for (int i = 0; i < abecedniZnaky.length(); i++)
                {
                    if (abecedniZnaky.charAt(i) == abecedniZnak)
                        {
                        index = i;
                        }
                }
            if (index >=0)
                {
                    znak = morseovyZnaky[index];
                }
            zprava2 += znak + " ";
        }
       System.out.printf("Znovu zakodovaná zpráva: %s\n", zprava2);
 
Odpovědět 6.12.2015 16:32
Avatar
Miroslav Bejlek:14.9.2016 17:15

Ahoj,
mám dotaz pro spojování řetězců mohu použít buď plus nebo příkaz concat().
String s1, s2, s3;
s3 = s1 + s2; nebo
s3 = s1.concat(s2)

dotaz mám v čem je rozdíl, podle mne je to stejné, pak nechápu proč tu speciální metodu vůbec zaváděli, tak si říkám, že asi nějaký rozdíl v tom bude, prosím řekněte mi jaký :-)

Děkuji :-)

 
Odpovědět 14.9.2016 17:15
Avatar
Dalibor Kužma:24.11.2016 19:59

viete mi povedať prečo môj prekladač koktá? Tu je kód:

Scanner sc = new Scanner (System.in, "Windows-1250");
        System.out.println("Vitajte v prekladači do Morseovky!");
        System.out.println("Vložte text na preklad:");
        String s = sc.nextLine();
        String preklad = "";
        String[] abeceda = {"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"};
        String[] mAbeceda = {".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....",
"..", ".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-",
"...-", ".--", "-..-", "-.--", "--.."};
        String[] text = s.split("");
        for ( String aZnak : text){
            String mZnak = "?";
            int index = -1;
            for (int i =0; i < abeceda.length; i++){
                if (abeceda[i].equals(aZnak)){
                    index = i;
                }
            if (index >= 0){
                mZnak = mAbeceda[index];
            }
            preklad += mZnak + " ";
            }

        }
        System.out.printf("Preložený text je: \n %s\n", preklad);
 
Odpovědět 24.11.2016 19:59
Avatar
pocitac770
Redaktor
Avatar
Odpovídá na Dalibor Kužma
pocitac770:24.11.2016 21:59

Chyba je v této části kódu, zkus nad tím zapřemýšlet ;)

for (int i =0; i < abeceda.length; i++){
        if (abeceda[i].equals(aZnak)){
                index = i;
        }
        if (index >= 0){
                mZnak = mAbeceda[index];
        }
        preklad += mZnak + " ";
}
 
Odpovědět 24.11.2016 21:59
Avatar
Odpovídá na pocitac770
Dalibor Kužma:25.11.2016 22:06

pocitac770 Ďakujem prišiel som na to. Problém bol v zátvorke :).

 
Odpovědět 25.11.2016 22:06
Avatar
gcx11
Redaktor
Avatar
gcx11:26.4.2017 22:14

Doplnil bych, že metoda split nebere jako parametr řetězec, ale regulární výraz.

Například rozdělení řetěžce na věty podle tečky nebude fungovat:

String text = "Dobrý den. Jmenuje se Jan Novák a učím se Javu. Docela mi to jde.";
String[] parts = text.split(".");
for (String s: parts){
      System.out.println(s);
 }

Napřed se musí upravit řetězec, aby nebyl brán jako regulární výraz:

String text = "Dobrý den. Jmenuje se Jan Novák a učím se Javu. Docela mi to jde.";
String[] parts = text.split(Pattern.quote("."));
for (String s: parts){
      System.out.println(s);
 }

Třída Pattern je z balíčku java.util.regex

Editováno 26.4.2017 22:15
 
Odpovědět 26.4.2017 22:14
Avatar
Radka Jánská:14.9.2017 23:56

Tak musím říci, že dekoder morseovky se povedl, ale seděla jsem u toho 2 hodiny čistého času! Zítra si to musím porovnat s Vaším řešením. Ze začátku jsem se zacyklila na tom, že jsem opět chtěla bezmyšlenkovitě použít metodu split() - kdo by se nad tím v deset večer zamýšlel ... teprve postupnou analýzou mi došlo, že nemám potřebný separátor a vzpomněla jsem si ze starších tutoriálů na metodu toCharArray() ... pak jen vybojovat porovnávání znaků ... nefunguje equals, ale operátor == (pomohl strýček google) a řešení je na světě :-) děkuji za tohle mozkové cvičení, nevím, jestli jsem našla nejelegantnější řešení, ale hlavně, že jsem ho našla :-)

 
Odpovědět  +2 14.9.2017 23:56
Avatar
Maroš Škumát:12.10.2017 20:56

Neviete mi niekto povedať kde mám chybu ?

Scanner sc = new Scanner(System.in,"Windows-1250");
        System.out.println("Zvoľte si operáciu");
        System.out.println("1 - preklad do morseovej abecedy");
        System.out.println("2 - preklad z morseovej abecedy");
        byte voľba = Byte.parseByte(sc.nextLine());
        String[] abeceda = {"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"};
        String[] mAbeceda = {".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....",
        "..", ".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-",
        "...-", ".--", "-..-", "-.--", "--.."};
        String sprava = "";
        String znak = "";
        int index = -1;
        switch(voľba)
        {
            case 1:
                System.out.println("Napíšte správu na preloženie: ");
                String preklad1 = sc.nextLine();
                preklad1 = preklad1.trim();
                preklad1 = preklad1.toLowerCase();
                String[] Preklad = preklad1.split("");
                for(String preklad : Preklad)
                {
                    for(int i = 0; i < abeceda.length; i++)
                    {
                        if(abeceda[i].equals(preklad))
                        {
                            index = i;
                        }
                        if(index > 0)
                        {
                        znak = mAbeceda[index];
                        }
                        }
                sprava += znak;
                }
                System.out.println("Dekódovaná správa: " + sprava);
                break;
 
Odpovědět 12.10.2017 20:56
Avatar
Odpovídá na Maroš Škumát
Jana Cibulková:13.10.2017 9:38

Aby to překládalo i písmeno a musí být if(index >=0){znak = mAbeceda[index];}
Chybí ti =

 
Odpovědět 13.10.2017 9:38
Avatar
Tereza Přibáňová:28.11.2017 11:25

Poradí mi někdo, jak to opravit? Začala sem se učit prográmko před cca týdnem a ať do toho zírám sebevíc, nevím, kde je to špatně (tuším že to for-loop? ...)

Scanner sc = new Scanner(System.in, "Windows-1250");
        System.out.println("zadejte zprávu k přeložení do Morzeovy abecedy: ");
        String zprava = sc.nextLine().toLowerCase().trim();
        String[] pismena_zpravy = zprava.split("");
        String nova_zprava = "";
        String[] abeceda = {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"};
        String[] morseovka = {".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....",
        "..", ".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-",
        "...-", ".--", "-..-", "-.--", "--.."};
        for (int j = 0; j< pismena_zpravy.length; j++){

        String morseuv_znak = "";
        for (int i = 0; i < abeceda.length; i++){
            int index = -1;
            if (abeceda[i].equals(pismena_zpravy[j])){
                index = i;
            }
            if (index >= 0){
            morseuv_znak = morseovka[index];
        }
            nova_zprava += morseuv_znak;
        }
    }
    System.out.println("Dekódovaná zpráva: \n" + nova_zprava);
}
}
 
Odpovědět 28.11.2017 11:25
Avatar
Odpovídá na Tereza Přibáňová
Tereza Přibáňová:28.11.2017 21:13

Tak už jsem na to přišla :D ... Nejradši bych to smazala, ale nechám to tu jako odstrašující případ ;)

 
Odpovědět 28.11.2017 21:13
Avatar
zitekv
Člen
Avatar
Odpovídá na Tereza Přibáňová
zitekv:28.11.2017 21:35

Ahoj,
pokud ti to nefunguje je dobré říci více o tom co nefunguje a co "reklamuješ".
Určitě to něco hlásí - a to je většinou zásadní pro hledání příčiny tzn. pokud se ptáš na problém je dobré přiložit chybové hlášení z IDE.

 
Odpovědět 28.11.2017 21:35
Avatar
Odpovídá na zitekv
Tereza Přibáňová:29.11.2017 21:59

Nic to nehlásilo, ale všechny znaky se vypsaly 26x ... Ale děkuju z upozornění, příště budu vědět :)

 
Odpovědět 29.11.2017 21:59
Avatar
MiroslavP
Člen
Avatar
MiroslavP:21.1.2018 19:44

Díky skvělému seriálu Java jsem opět objevil kouzlo programování. Děkuji MiP

Program dekoder Morse:
public class JavaApplication40 {

/**
* @param args the command line arguments
*/
public static void main(String[] args) {
Scanner sc = new Scanner(System­.in,"Windows-1250");
Vzorové soubory znaků:
String[] abecedniZnaky = {"A","B","C",­"D","E","F","G","H","I",­"J","K","L","M","N","O",­"P","Q","R","S",
"T","U","V","­W","X","Y","Z"};
String[] morseSoubor = {".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....",
"..", ".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-",
"...-", ".--", "-..-", "-.--", "--.."};
String oddelovac = " "; //oddělovač mezi Morse znaky (mezera)
//Morse zpráva k dekódování, jednotlive znaky jsou odděleny mezerou
String abecedniZprava = "ITNETWORK";
String kodovanaZprava = "";
int index = -1;
pořadí morse znaku v souboru v přépadě shody je rúzné od -1
int j = 0; //slouží pro iteraci v abecednim souboru
System.out.prin­tln("Kodér Morseovy abecedy");
System.out.prin­t("Zpráva k zakódování: ");
System.out.prin­tln(abecedniZ­prava);
//Rozdělení Abecední zprávy na jednotlivé Abecední znaky
String[] znaky = abecedniZprava­.split("");
int l = znaky.length;
for (int i=0; i < l; i++){
// System.out.prin­tln(znaky[i]);
}
//iterace Jednotlivých abecednich znaků a přiřazení příslušného Morse znaku
for (int i = 0; i < l ;i++){
while (index < 0){
if (znaky[i].equ­als(abecedniZ­naky[j]))
{
index = j;
kodovanaZprava = kodovanaZprava + String.format("%s%s",m­orseSoubor[in­dex],oddelovac);
}
else{
j++;
}
}
index = -1;
j = 0;
}
System.out.prin­tln("Kódovaná zpráva: " +kodovanaZprava);
}
}

 
Odpovědět 21.1.2018 19:44
Avatar
Moni
Člen
Avatar
Moni:19.3.2018 9:11

Když to udělám podobným způsobem tak mi to jede, ale já bych potřebovala jak převést char na string.
for(char aZnak : slova.toCharA­rray()){
for(int i=0;i< abeceda.length;i++){

if(aZnak == abeceda[i]){

 
Odpovědět 19.3.2018 9:11
Avatar
pocitac770
Redaktor
Avatar
Odpovídá na Moni
pocitac770:20.3.2018 1:14

Pokud chceš String z takto více znaků, stačí klasicky "přičítat" char ke Stringu

String s = "";
//....
s += aZnak;

Pokud ale výslovně postřebuješ z jednoho charu String (což nedává v takovémto příkladu smysl), tak se jedná o

String s = String.valueOf(aZnak);
Editováno 20.3.2018 1:15
 
Odpovědět 20.3.2018 1:14
Avatar
Moni
Člen
Avatar
Moni:20.3.2018 7:28

Jo, super, už to jede. Jedna se o předělání většího počtu prográmků a tak se mi to nechtělo celé rozkopávat. A tohle je nejjednodušší. Díky moc.

 
Odpovědět 20.3.2018 7:28
Avatar
Josef Pospíšil:6.4.2018 13:06

V článku je, že:

CompareTo()
Umožňuje porovnat dva řetězce podle abecedy. Vrací -1 pokud je první řetězec před řetězcem v parametru, 0 pokud jsou stejné a 1 pokud je za ním:

Ale já když to zkoušel, tak to háže jiné číslo a to v závislosti na tom jak daleko jsou abecedně od sebe. Takže -1 a 1 je to jen v případě, že se porovnávají slova, jejichž písmena abecedně sousedí jinak je tam třeba mezi "akát" a "kráva" -10.

 
Odpovědět 6.4.2018 13:06
Avatar
dommynyk
Člen
Avatar
dommynyk:13.5.2018 15:02
Scanner sc = new Scanner(System.in);
                System.out.println("zdj ret: ");
                String mes = sc.nextLine();
                String dek = "";
                String abc = "abcdefghijklmnopqrstuvwxyz";
                String[] mor = {".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....",
                                "..", ".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-",
                                "...-", ".--", "-..-", "-.--", "--.."};
                mes.toLowerCase();
                //mes.trim();
                for(char znk : mes.toCharArray()) {
                        String mozn = null;
                        int index = 0;
                        for(int i = 0; i< mes.length(); i++) {
                                if(String.valueOf(abc.charAt(i)).equals(String.valueOf(znk)))
                                        index = i;
                                }
                                if(index >= 0) {
                                        dek += mor[index];
                                }
                        }
                        System.out.print(dek);
Odpovědět 13.5.2018 15:02
_________________________
Avatar
dommynyk
Člen
Avatar
dommynyk:15.5.2018 18:58

Mohlo by to byť aj takto? Myslím, že všetko funguje ako má. :)

Scanner sc = new Scanner(System.in);
               System.out.println("vety: ");
               String vty = sc.nextLine();
               String[] sml = {":) " ,":D ", ":P "};
               int smll = 0;
               String[] vt = vty.split(" ");
               String vs = "";
               String inte = "!.?";
               for(String v : vt) {
                   for(char h: inte.toCharArray()) {
                          if(String.valueOf(v).contains(String.valueOf(h))) {
                                  if(smll == 3) {
                                          smll = 0;
                                          vs += v.replace(String.valueOf(h), String.valueOf(sml[smll]));
                                  smll++;  break;
                                  }
                                  else {
                                   vs += v.replace(String.valueOf(h), String.valueOf(sml[smll]));
                                  smll++;
                                 }
                          }
                   }
            }
        System.out.println(vs);
Odpovědět 15.5.2018 18:58
_________________________
Avatar
Monika Badačová:14.8.2018 18:46

Prosím, neviete poradiť, kde je chyba?

String s = "ahoj";
System.out.prin­tf("Pôvodná správa: %s\n", s);

String sprava = "";

String []abecedneZnaky = {"a", "b", "c", "d", "e", "f", "g", "h",
"i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u",
"v", "w", "x", "y", "z"};
String[] morseoveZnaky = {".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....",
"..", ".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-",
"...-", ".--", "-..-", "-.--", "--.."};

String []znaky = s.split(" ");

for (String abecedniZnak : znaky) {
char morseovZnak = '?';

int index = -1;
for (int i = 0; i < abecedneZnaky­.length; i++) {
if (abecedneZnaky[i]­.equals(abeced­niZnak))
index = i; }

if (index >= 0) { // znak nalezen
morseovZnak = morseoveZnaky[in­dex]; } //systém vypisuje: incompatible types: String cannot be converted to char
sprava += morseovZnak+" "; }
System.out.prin­tf("Dekódovaná zpráva: \n %s\n", sprava); } }

 
Odpovědět 14.8.2018 18:46
Avatar
Odpovídá na Monika Badačová
Matúš Olejník:14.8.2018 19:23

Ahoj problém je v tom, že morseovZnak máš typu char a morseoveZnaky je pole Stringov a teda morseoveZnaky[in­dex] bude typu String. Jedno riešenie by mohlo byť že morseovZnak prerobíš na typ String

Ak by si sa nudila, tu som ti napísal kratšiu verziu aj s komentármi :)

public String stringToMorseEncode(String msg) {

//    ASCII hodnota znaku A je 65 preto nepotrebujeme takto rucne ukladat pismena do pola
//    String[] abecedneZnaky = {"a", "b", "c", "d", "e", "f", "g", "h",
//        "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u",
//        "v", "w", "x", "y", "z"};

    //TODO pracovat s parametrom funkcie
    String povodnaSprava = "ahoj";
    System.out.printf("Pôvodná správa: %s\n", povodnaSprava);

    String vyslednaSprava = "";

    String[] morseoveZnaky = {
            ".-", "-...", "-.-.", "-..", ".",
            "..-.", "--.", "....", "..", ".---",
            "-.-", ".-..", "--", "-.", "---",
            ".--.", "--.-", ".-.", "...", "-",
            "..-", "...-", ".--", "-..-", "-.--",
            "--.."
    };

    //TODO doplnit kontrolu na ine znaky nez pismena atd
    for(int i = 0; i < povodnaSprava.length(); i++) {
        //String na pozicii i v povodnaSprava prevedieme na uperCase znak pretoze nizsie
        //od jeho ASCII hodnoty odratavame ASCII hodnotu znaku 'A' a vysledok pouzijeme ako
        //index do pola morseoveZnaky
        char znak = Character.toUpperCase(povodnaSprava.charAt(i));
        int asciiHodnota = (int) znak;

        //TODO pouzit StringBuilder - pozri Google ;)
        vyslednaSprava += morseoveZnaky[asciiHodnota - 65]; // alebo asciiHodnota - (int) 'A'
        vyslednaSprava += " ";
    }

    System.out.printf("Zakódovaná zpráva: \n %s\n", vyslednaSprava);

    return vyslednaSprava;
}
Editováno 14.8.2018 19:25
Odpovědět  +1 14.8.2018 19:23
/* I am not sure why this works but it fixes the problem */
Avatar
Monika Badačová:14.8.2018 19:30

super :) ďakujem ti

 
Odpovědět  +1 14.8.2018 19:30
Avatar
Libor Šimo (libcosenior):28.9.2018 6:32

Neviem, či si to niekto všimol, ale je tam chybička:
"CompareTo()
Umožňuje porovnat dva řetězce podle abecedy. Vrací -1 pokud je první řetězec před řetězcem v parametru, 0 pokud jsou stejné a 1 pokud je za ním:"

Vracia záporné alebo kladné číslo - rozdiel medzi umiestnením v abecede. Nula je jasná.

Odpovědět 28.9.2018 6:32
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Avatar
Jiří Mareček:2.11.2018 11:59

Zdravím všechny!

Jsem úplný začátečník a zajímá mě jedna věc:
if (morseovyZnaky[i] - "i" v hranatých závorkách má indikovat, že se jedná o index pole morseovyZnaky?

Děkuji za Váš čas!

 
Odpovědět 2.11.2018 11:59
Avatar
mhmarekholly
Člen
Avatar
mhmarekholly:28.11.2018 16:44

Ahoj prosím vás v tej opačnej morzeovke je nutné dávať znaky abecedy do poľa stringov?

 
Odpovědět 28.11.2018 16:44
Avatar
Nessay
Člen
Avatar
Nessay:25. ledna 14:45
System.out.println("Prosim zadaj spravu, ktoru zasifrujem do morzeovky:");
       String in = sc.nextLine();
       in = in.toLowerCase();
      String[] morseovyZnaky = {".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--.."};
       String morzeovka = "";
       String[] slova = in.split(" ");                                   // spravu rozdelime do slov
       for (String slovo : slova){
           String morzeovZnak = "?";
           int index = -1;
           int dlzkaSlova = 0 ;                                          // slova rozdelime do pismen a tie na ASCII hodnotu
               for (int i = 0; i < slovo.length(); i++){
                   dlzkaSlova ++;
               char pismenko = slovo.charAt(i);
               int o = (char)pismenko;
               index = o - 97;                                             // 97 je ASCII hodnota 'a' a pole zacina indexom '0'
               morzeovZnak = morseovyZnaky[index];
               morzeovka += morzeovZnak;
               if (dlzkaSlova == slovo.length()){
                   morzeovka += " ";
               }
           }
        }
        System.out.printf("Tvoja sprava v morzeovke vyzera takto: \"%s\"\n", morzeovka);

Da sa prosim vas "medzerovat" slova v sprave aj inak? (viem mohlo byt 2.
for (char pismenko : slovo.toCharA­rray())

 
Odpovědět 25. ledna 14:45
Avatar
Matěj Bína
Člen
Avatar
Matěj Bína:23. března 17:57

OK, takže... zpětnej překladač mi dělal blbiny kvůli tomu, že jsem se nemorseovské znaky snažil ošetřit přidáním

else {
        morseuvZnak = "?";
}

Prostě buď vypsal jedno písmeno a samý otazníky, nebo rovnou samý otazníky (proč překládal správně jenom písmeno z jsem se nikdy nedopátral).
Pak jsem viděl kód dommynyka o pár komentů výš, a když jsem za svůj kód u if přidal break; šlape to jak po másle.
Takže... je u if / else nutné používat break; nebo je možný, že chyba byla někde jinde?

 
Odpovědět 23. března 17:57
Avatar
zitekv
Člen
Avatar
zitekv:23. března 22:29

Když sem nevložíš kód toho cyklu, co ti dělá problémy, tak to bez věštecké koule nejde poradit.
Naštěstí jednu mám :-)
Podle všeho v cyklu projíždíš celou abecedu a pokud je shoda přiřadíš písmeno, ale cyklus nezastavíš ( a to právě udělá ten break - tzn. s if else to nemá žádnou souvislost) a další kontrolou ti to zase vloží otazník. Akorát z je na konci, tak to tam zůstane.
Je to tak?

 
Odpovědět 23. března 22:29
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 51 zpráv z 51.