Merkkien esiintyminen

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.");
}
4269
Äänestä

Muut lukivat myös

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 ;)

Äänestä

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...

Äänestä

Miksi ihmeessä koodi toimii ilman että
pakkomuutetaan se char intiksi??



for (i = 0; i < sMerkit.length(); i )
merkkitaulu[(int)sMerkit.charAt(i)] ;

Äänestä
  • 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] ;

    Äänestä

Kommentoi aloitusta


PetteriPunakuono kirjoitti:

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.");
}

Anonyymi
5000

Ilmoita asiaton sisältö

  • Sisältää materiaalia, joka on loukkaavaa, herjaavaa, rasistista, uhkailevaa tai ahdistelevaa.

  • Materiaali sisältää nimiä, yhteystietoja tai muita henkilökohtaisia tietoja. Julkisuuden henkilöistä, julkisissa viroissa toimivista ihmisistä sekä yritysten vastuuhenkilöistä saa keskustella työhön liittyen. Myös yksityiselämään liittyvistä asioista voi keskustella siltä osin, kuin niistä on julkisesti kerrottu.

  • Sisältää lapsille haitallista tai heiltä kiellettyä materiaalia. Seksuaalinen sisältö on sallittua aiheeseen tarkoitetuilla palstoilla, joiden ikäraja on 18 vuotta.

  • Lainvastaista sisältöä voi olla mm. yksityiselämää loukkaavan tiedon levitys, kiihottaminen kansanryhmää vastaan, laiton uhkaaminen, alaikäisiin liittyvä seksuaalinen sisältö/grooming, petokset, identiteettivarkaudet, kunnianloukkaukset ja tekijänoikeusrikkomukset.

  • Sisältö ei liity palstan tai keskusteluketjun aiheeseen.

  • Viesti ei ole suomea tai ruotsia (pl. International Forums), se sisältää mainontaa, se sisältää tekijänoikeuksin suojattua materiaalia, se on massapostitus tai jokin muu syy.

Jaa keskustelu