Koodi tulostaa merkkijonon merkit ja merkkien esiintymiskerrat. Tää koodi toimii kun tauti, mutta mä en tajuu miks toi (char)i
toimii siinä tulostuksessa? Se i on intti siinä taulukossa, ja kun se pakotetaan chariksi, mistä se tietää mikä merkki se on?
public static void main(String[] args)
{
Kirjoita.println("\nSyötä merkkijono:");
String sMerkit = Lue.rivi();
int[] merkkitaulu = new int[65535];
int i;
for (i = 0; i < sMerkit.length(); i )
merkkitaulu[sMerkit.charAt(i)] ;
for (i = 0; i < 65535; i )
if (merkkitaulu[i] > 0)
System.out.println("Merkki '" (char)i "' esiintyi " merkkitaulu[i] " kertaa.");
}
toimii siinä tulostuksessa? Se i on intti siinä taulukossa, ja kun se pakotetaan chariksi, mistä se tietää mikä merkki se on?
public static void main(String[] args)
{
Kirjoita.println("\nSyötä merkkijono:");
String sMerkit = Lue.rivi();
int[] merkkitaulu = new int[65535];
int i;
for (i = 0; i < sMerkit.length(); i )
merkkitaulu[sMerkit.charAt(i)] ;
for (i = 0; i < 65535; i )
if (merkkitaulu[i] > 0)
System.out.println("Merkki '" (char)i "' esiintyi " merkkitaulu[i] " kertaa.");
}
Vastaukset 4
Vanhimmat
Javan merkkitietotyyppi char on unicode merkki. Se on oikeastaan 16 bittinen numero, eli sen arvoalue on väliltä 0-65535.
Tuossa nyt vain loopataan kaikki mahdolliset unicode merkit läpi. Mitään tietoa ei menetetä vaikka int on suurempi tietotyyppi kun silmukassa käydään vain tuo char tyypin arvoalue läpi.
En ole mikään java guru mut jospa tuosta nyt jotain tolkkua sai..
Lisäyksenä:
Toimiihan se tuolla lailla varsin suoraviivaisesti. Homman voisi toteuttaa vaan fiksumminkin jolloin ei tarvitsisi silmukoida koko unicoden arvoaluetta.
Silloin käytettäisiin int taulukon sijaan "kehittyneempää" tietotyyppiä kuten hashmap/dictionary tai mikä se nyt javassa on lieneekään. Ihan nyt vain jos harjotuksena kiinnostaa ;)
Onkohan tämä jokin koti tehtävä kun niin usein kysytään. :) Lue keskustelu "Alkeet tökkii", jossa käsiteltiin aivan samaa asiaa ja oli aivan sama koodi esimerkki. Korjaa myös se virhe siitä koodistasi, eli korvaa se 65535 arvolla 65536, sillä kyllä Java ainakin merkin \uFFFF hyväksyy string:iin.
Mitähän tässä nyt sitten selittäisi. ;) Merkkihän siis on sama asia kuin numero, eli jokainen merkki koodataan jollakin numerolla väliltä 0 – 65535 (Siis yhteensä 65536 eri merkkiä/numeroa/koodia). Kun haluat tulostaa näytölle merkin jonka numero on 65 niin voit tehdä sen seuraavasti.
System.out.println((char) 65);
Jos puolestaan haluat tulostaa merkin 'a' numeron (eli koodin), voit tehdä sen seuraavasti:
System.out.println((int) 'a');
Koska merkki vastaa aina jotakin numeroa niin seuraavat lauseet ovat myös ihan sallittuja:
System.out.println('a'*2 'b');
merkkitaulu['m'] ;
...
En tiedä ymmärtäisitkö paremmin jos kirjoittaisit nuo kolme viimeistä riviä koodistasi muotoon:
for (int merkinkoodi = 0; merkinkoodi < 65535; merkinkoodi )
if (merkkitaulu[merkinkoodi] > 0)
System.out.println("Merkki " (char) merkinkoodi " esiintyy " merkkitaulu[merkinkoodi] " kertaa.");
Muutat vielä tuon "merkkitaulu" nimen koodistasi vaikka muotoon "merkkikoodinesiintymismäärät", niin josko sitten pääsisit jyvälle mikä on koko homman juoni. En nyt tuohon ylle muuttanut tuota 65535 juttua...
Miksi ihmeessä koodi toimii ilman että
pakkomuutetaan se char intiksi??
for (i = 0; i < sMerkit.length(); i )
merkkitaulu[(int)sMerkit.charAt(i)] ;
Sori jos vastaan turhaan. En tiennyt oliko kysymyksesi vain retorinen kysymys alkuperäisen kysymyksen kirjoittajalle. :)
Vastaus:
Koska 16 bittiä (char) mahtuu 32 bittiin (int) niin tämän takia Java pystyy tekemään (ja tekeekin) tyyppimuunnoksen automaattisesti koska yhtään bittiä (eli tietoa) ei menetetä.
Muuta:
Taulukon käsittely menee eri tieto tyypeillä alla olevan listauksen mukaisesti. Eli long tyyppi pitää itse pakkomuuttaa sillä java ei voi tätä tehdä automaattisesti koska se aiheuttaa bittien häviämistä (koska long on 64 bittiä).
1: merkkitaulu[(byte) 3] ;
2: merkkitaulu[(char) 3] ;
3: merkkitaulu[(int) 3] ;
4: merkkitaulu[(int) (long) 3] ;