Tekstitiedoton indeksointi

Pitäisi saada iso (satoja megoja) tekstitiedosto (ASCII) indeksoitua. Loytyyko valmista softaa?

Ohjeman pitäisi ignoorata spacet ja pistää löydetyt stringit esiintymisjärjestykseen. Outputin pitäisi näyttää jokseenkin tältä:
auto 41200
että 39840
kissa 23098
mutta 10988
jne...

Taidot ei riitä että tekis itte...

Thanks, Timo
111060
Äänestä

Muut lukivat myös

Vastaukset 11

Vanhimmat

eiköhän tuo mene itsestää useimilla tietokantaohjelmilla. luet sisään aineiston ja sitten luot yhteenvetoraportin?

Äänestä

En tiedä onko valmista, mutta tässä tekemäni Java koodi joka hoitaa asian, en tiedä onko siitä apua:


--- tiedosto alkaa (LaskijaOhjelma.java) ---

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;


public class LaskijaOhjelma {
   
   public LaskijaOhjelma() {
   }
   
   public static void main(String[] args) throws IOException {
      File file = new File(args[0]);
      FileInputStream   fin       = new FileInputStream(file);
      SanaLaskuri    laskuri = new SanaLaskuri();
      
      char[]   merkit = new char[1000];
      int      pituus = 0;
      int      merkki = 0;
      
      while (merkki != -1) {
         if (Character.isLetter(merkki = fin.read())) {
            merkit[pituus ] = (char) Character.toLowerCase(merkki);
         } else if (pituus != 0) {
            laskuri.lisääSana(new String(merkit, 0, pituus));
            pituus   = 0;
         }
      }

      fin.close();
      ArrayList lista = laskuri.annaSanatJaMäärät();
      Collections.sort(lista);
      
      for (SanaJaMäärä sanaJaMäärä: lista)
         System.out.println(sanaJaMäärä);
   }
}

--- tiedosto loppuu ---



--- tiedosto alkaa (SanaLaskuri.java) ---

import java.util.ArrayList;
import java.util.HashMap;


public class SanaLaskuri {

   private HashMap sanat;
   
   public SanaLaskuri() {
      sanat = new HashMap();
   }
      
   public void lisääSana(String sana) {
      SanaJaMäärä sjm = sanat.get(sana);
      
      if (sjm == null) {
         sanat.put(sana, new SanaJaMäärä(sana));
      } else {
         sjm.kavataMäärää();
      }
   }

   public ArrayList annaSanatJaMäärät() {
      return new ArrayList(sanat.values());
   }   
}

--- tiedosto loppuu ---



--- tiedosto alkaa (SanaJaMäärä.java) ---

public class SanaJaMäärä implements Comparable {

   private final String   sana;
   private int            määrä;

   public SanaJaMäärä(String sana) {
      this.sana = sana;
      this.määrä = 1;
   }
   
   public int kavataMäärää() {
      return määrä;
   }
      
   public String toString() {
      return sana " " määrä;
   }

   public int compareTo(SanaJaMäärä sanaJaMäärä) {
      return sanaJaMäärä.määrä - määrä;
   }
}

--- tiedosto loppuu ---


Jos saat käännettyä tuon (vaatii Java 1.5:n), niin saat sen jälkeen tulostettua listan komennolla "java LaskijaOhjelma teso.txt", jossa teso.txt sanoja sisältävän tekstitiedoston nimi. Testasin ohjelmaa 17 Mt tiedoston kanssa, niin sen läpikäynti kesti n. 15s. Tulos oli seuraava:

the 183386
and 91894
of 89362
a 71711
to 71694
i 57578
in 47558
that 42564
it 41969
was 39273

...

montant 1
hinging 1
paukahdus 1
terrorised 1
medicalschrilt 1
moissons 1
blob 1
mieltäni 1
luonaan 1
taivuksissa 1
neitsyen 1

Äänestä
  • Taisin taas käsittää kysymyksen väärin, (esimerkkisi hämäsi). Edellinen ohjelma laski vain eri sanojen esiintymismäärät ja tulosti ne lopuksi. Tässä olisi nyt varsinaisen indeksoijan lähdekoodi (joka on paljon yksinkertaisempi kuin edellinen ohjelma):


    --- tiedosto alkaa (Indeksoija.java) ---

    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.util.HashMap;

    public class Indeksoija {
       
       public Indeksoija() {      
       }
       
       public static void main(String[] args) throws IOException {
          File       file = new File(args[0]);
          FileInputStream         fin    = new FileInputStream(file);
          HashMap   sanat = new HashMap();
          String index = null;
          String       sana = null;
          
          char[]   merkit = new char[1000];
          int      pituus = 0;
          int      merkki = 0;
          int indexm = 0;
          
          while (merkki != -1) {
             if (Character.isLetter(merkki = fin.read())) {
                merkit[pituus ] = (char) Character.toLowerCase(merkki);
             } else if (pituus != 0) {
                sana = new String(merkit, 0, pituus);
                pituus = 0;
                
                if ((index = sanat.get(sana)) == null) {
                   index = Integer.toString(indexm );
                   sanat.put(sana, index);
                }
                
                System.out.println(sana " " index);
             }
          }
       
          fin.close();
       }
    }

    --- tiedosto loppuu ---


    Tuon voi kääntämisen jälkeen käynnistää komennolla "java Indeksoija testi.txt", jossa testi.txt on indeksoitavan teksti tiedoston nimi. 17 Mt:n tiedoston indeksointiin meni noin 25s. Ohjelma antaa siis seuran kaltaisen tuloksen:

    the 0
    project 1
    gutenberg 2
    ebook 3
    of 4
    the 0
    adventures 5
    of 4
    sherlock 6
    holmes 7
    by 8
    sir 9
    arthur 10
    conan 11
    doyle 12
    in 13
    our 14
    series 15
    by 8
    sir 9
    arthur 10
    conan 11
    doyle 12
    copyright 16
    laws 17
    are 18
    changing 19
    all 20
    over 21
    the 0
    world 22
    be 23
    sure 24
    to 25
    check 26
    the 0
    ...

    Äänestä

  • plaah kirjoitti:

    Taisin taas käsittää kysymyksen väärin, (esimerkkisi hämäsi). Edellinen ohjelma laski vain eri sanojen esiintymismäärät ja tulosti ne lopuksi. Tässä olisi nyt varsinaisen indeksoijan lähdekoodi (joka on paljon yksinkertaisempi kuin edellinen ohjelma):


    --- tiedosto alkaa (Indeksoija.java) ---

    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.util.HashMap;

    public class Indeksoija {
       
       public Indeksoija() {      
       }
       
       public static void main(String[] args) throws IOException {
          File       file = new File(args[0]);
          FileInputStream         fin    = new FileInputStream(file);
          HashMap   sanat = new HashMap();
          String index = null;
          String       sana = null;
          
          char[]   merkit = new char[1000];
          int      pituus = 0;
          int      merkki = 0;
          int indexm = 0;
          
          while (merkki != -1) {
             if (Character.isLetter(merkki = fin.read())) {
                merkit[pituus ] = (char) Character.toLowerCase(merkki);
             } else if (pituus != 0) {
                sana = new String(merkit, 0, pituus);
                pituus = 0;
                
                if ((index = sanat.get(sana)) == null) {
                   index = Integer.toString(indexm );
                   sanat.put(sana, index);
                }
                
                System.out.println(sana " " index);
             }
          }
       
          fin.close();
       }
    }

    --- tiedosto loppuu ---


    Tuon voi kääntämisen jälkeen käynnistää komennolla "java Indeksoija testi.txt", jossa testi.txt on indeksoitavan teksti tiedoston nimi. 17 Mt:n tiedoston indeksointiin meni noin 25s. Ohjelma antaa siis seuran kaltaisen tuloksen:

    the 0
    project 1
    gutenberg 2
    ebook 3
    of 4
    the 0
    adventures 5
    of 4
    sherlock 6
    holmes 7
    by 8
    sir 9
    arthur 10
    conan 11
    doyle 12
    in 13
    our 14
    series 15
    by 8
    sir 9
    arthur 10
    conan 11
    doyle 12
    copyright 16
    laws 17
    are 18
    changing 19
    all 20
    over 21
    the 0
    world 22
    be 23
    sure 24
    to 25
    check 26
    the 0
    ...

    Eka koodi on sen joka hoitaa homman jonka halusin.

    Kiitos paljon, Timo

    Äänestä

  • Terve,

    Yritin kääntää parhaani mukaan, mutta pukkaa virheilmoitusta. Mikäköhän neuvoksi?

    Kiitos, Timo

    -----------------------------------------------
    C:\Program Files\Java\jdk1.5.0_06\Freq anal>..\bin\javac laskijaohjelma.java san
    ajamaara.java sanalaskuri.java
    laskijaohjelma.java:9: class LaskijaOhjelma is public, should be declared in a f
    ile named LaskijaOhjelma.java
    public class LaskijaOhjelma {
    ^
    sanajamaara.java:2: class SanaJaMaara is public, should be declared in a file na
    med SanaJaMaara.java
    public class SanaJaMaara implements Comparable {
    ^
    sanalaskuri.java:6: class SanaLaskuri is public, should be declared in a file na
    med SanaLaskuri.java
    public class SanaLaskuri {
    ^
    3 errors
    ------------------------------------------------

    Äänestä

  • Timo kirjoitti:

    Terve,

    Yritin kääntää parhaani mukaan, mutta pukkaa virheilmoitusta. Mikäköhän neuvoksi?

    Kiitos, Timo

    -----------------------------------------------
    C:\Program Files\Java\jdk1.5.0_06\Freq anal>..\bin\javac laskijaohjelma.java san
    ajamaara.java sanalaskuri.java
    laskijaohjelma.java:9: class LaskijaOhjelma is public, should be declared in a f
    ile named LaskijaOhjelma.java
    public class LaskijaOhjelma {
    ^
    sanajamaara.java:2: class SanaJaMaara is public, should be declared in a file na
    med SanaJaMaara.java
    public class SanaJaMaara implements Comparable {
    ^
    sanalaskuri.java:6: class SanaLaskuri is public, should be declared in a file na
    med SanaLaskuri.java
    public class SanaLaskuri {
    ^
    3 errors
    ------------------------------------------------

    luokka LaskijaOhjelma on julkinen, joten se pitäisi määritellä tiedostossa nimeltä LaskijaOhjelma.java

    Eli lähdekoodi pitäis olla tiedostossa, jossa tiedoston nimi vastaa juuri tuota luokan nimeä.

    Nyt sulla on pienillä kirjaimilla noi luokkien nimet...

    Äänestä

  • Piru kirjoitti:

    luokka LaskijaOhjelma on julkinen, joten se pitäisi määritellä tiedostossa nimeltä LaskijaOhjelma.java

    Eli lähdekoodi pitäis olla tiedostossa, jossa tiedoston nimi vastaa juuri tuota luokan nimeä.

    Nyt sulla on pienillä kirjaimilla noi luokkien nimet...

    Pitää muuten olla javasta versio 1.5.0_6 että voi käyttää noita

    HashMap

    sulkeita noissa määrittelyissä esim.

    ArrayList lista = new ArrayList();

    Äänestä

  • Timo kirjoitti:

    Terve,

    Yritin kääntää parhaani mukaan, mutta pukkaa virheilmoitusta. Mikäköhän neuvoksi?

    Kiitos, Timo

    -----------------------------------------------
    C:\Program Files\Java\jdk1.5.0_06\Freq anal>..\bin\javac laskijaohjelma.java san
    ajamaara.java sanalaskuri.java
    laskijaohjelma.java:9: class LaskijaOhjelma is public, should be declared in a f
    ile named LaskijaOhjelma.java
    public class LaskijaOhjelma {
    ^
    sanajamaara.java:2: class SanaJaMaara is public, should be declared in a file na
    med SanaJaMaara.java
    public class SanaJaMaara implements Comparable {
    ^
    sanalaskuri.java:6: class SanaLaskuri is public, should be declared in a file na
    med SanaLaskuri.java
    public class SanaLaskuri {
    ^
    3 errors
    ------------------------------------------------

    Kuten Piru tuossa yllä neuvoi, niin olet kopioinut tiedostojen nimet väärin. Muuta tiedostojen nimet alla olevan listan mukaisesti, ja yritä kääntää sen jälkeen uudelleen.

    laskijaohjelma.java => LaskijaOhjelma.java
    sanalaskuri.java => SanaLaskuri.java
    sanajamaara.java => SanaJaMäärä.java

    Huomaa siis isot ja pienet kirjaimet sekä ääkköset. Kääntämisestä vielä sen verran, että voit kääntää tiedostot komennolla "javac *.java", jollon sun ei tarvitse hakata kaikkien tiedostojen nimiä javac:n parametriksi.

    Äänestä

  • plaah kirjoitti:

    Kuten Piru tuossa yllä neuvoi, niin olet kopioinut tiedostojen nimet väärin. Muuta tiedostojen nimet alla olevan listan mukaisesti, ja yritä kääntää sen jälkeen uudelleen.

    laskijaohjelma.java => LaskijaOhjelma.java
    sanalaskuri.java => SanaLaskuri.java
    sanajamaara.java => SanaJaMäärä.java

    Huomaa siis isot ja pienet kirjaimet sekä ääkköset. Kääntämisestä vielä sen verran, että voit kääntää tiedostot komennolla "javac *.java", jollon sun ei tarvitse hakata kaikkien tiedostojen nimiä javac:n parametriksi.

    No niin, nyt kääntyy, mutta ajettaessa antaa virheen: C:\Program Files\Java\jdk1.5.0_06\Freq anal>java LaskijaOhjelma eula.txt
    Exception in thread "main" java.lang.NoClassDefFoundError: LaskijaOhjelma

    Mikäköhän tämän aiheuttaa?

    Thanks, Timo

    Äänestä

  • Timo kirjoitti:

    No niin, nyt kääntyy, mutta ajettaessa antaa virheen: C:\Program Files\Java\jdk1.5.0_06\Freq anal>java LaskijaOhjelma eula.txt
    Exception in thread "main" java.lang.NoClassDefFoundError: LaskijaOhjelma

    Mikäköhän tämän aiheuttaa?

    Thanks, Timo

    Viittaisi siihen ettei Java ei löydä "LaskijaOhjelma.class" tiedostoa. Tarkista että kyseisen tiedosto on hakemissa. Jos kyseinen tiedosto on kuitenkin hakemistosta, niin tällöin Java ei todennäköisesti yritä etsiä sitä siitä hakemistosta. Kokeile tällöin lisätä CLASSPATH:iin ns. tämä hakemisto (eli "."), alla olevalla komennolla:

    SET CLASSPATH=.;%CLASSPATH%

    Tai jollei tuo auta, niin kokeile vielä sen jälkeen ottaa koko CLASSPATH:n pois komennolla:

    SET CLASSPATH=

    Äänestä

  • plaah kirjoitti:

    Viittaisi siihen ettei Java ei löydä "LaskijaOhjelma.class" tiedostoa. Tarkista että kyseisen tiedosto on hakemissa. Jos kyseinen tiedosto on kuitenkin hakemistosta, niin tällöin Java ei todennäköisesti yritä etsiä sitä siitä hakemistosta. Kokeile tällöin lisätä CLASSPATH:iin ns. tämä hakemisto (eli "."), alla olevalla komennolla:

    SET CLASSPATH=.;%CLASSPATH%

    Tai jollei tuo auta, niin kokeile vielä sen jälkeen ottaa koko CLASSPATH:n pois komennolla:

    SET CLASSPATH=

    Kiitos.

    Nyt toimii ja pelittää.

    -timo

    Äänestä

Kommentoi aloitusta


Timo kirjoitti:

Pitäisi saada iso (satoja megoja) tekstitiedosto (ASCII) indeksoitua. Loytyyko valmista softaa?

Ohjeman pitäisi ignoorata spacet ja pistää löydetyt stringit esiintymisjärjestykseen. Outputin pitäisi näyttää jokseenkin tältä:
auto 41200
että 39840
kissa 23098
mutta 10988
jne...

Taidot ei riitä että tekis itte...

Thanks, Timo

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