Toon posts:

[Java] Regelnummers textfile

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ten eerste, ik ben nog niet zo heel lang bezig met Java maar ik loop nu al tegen een probleem aan.

Wat wil ik met mijn programma
1) De hele file ingelezen als een string
2) Ik ga met een breakiterator.getSentenceInstance de zinnen er uit halen
3) Ik wil van deze zin een aantal dingen opslaan in een database waaronder het regelnummer.

Dit laatste geeft aan waar de gevonden zin in de textfile terug is te vinden. Het probleem hiermee is dat er meerdere zinnen op een line kunnen staan en ook langer dan één line kunnen zijn. Gewoon de linefeeds tellen heeft daardoor niet zo veel zin.

Nu dacht ik dat ik een oplossing had gevonden:
1) Bij het inlezen een Vector aanmaken die bijhoudt hoeveel hoeveel chars er op één regel in het bestand staan.

Dus dan krijg je een lijstje:
[1][150]
[2][250]
[3][350]

Dus op regel 0 staan dan de chars 0 tot 150, op regel 1 de chars 151 tot 250 en op regel 3 de chars 251 tot 350.

2) Bij het parsen van de zinnen weet ik bij welke char de zin begint dus dan loop ik even het lijstje door met een "if (start >= thisline && start <= nextline)" en dan heb ik de regenummer te pakken. Nu zit daar alleen het probleem. Dat gaat toch zo ontzettend traag!

Welke code heb ik gebruikt:
Bij het inlezen:
Java:
1
2
3
4
5
6
7
8
9
10
11
12
Vector regelnummers = new Vector();
try {
   FileReader fin = new FileReader(this.locatie);
   BufferedReader filein = new BufferedReader(fin);
   instr = filein.readLine();
   while (instr != null) {
   textje = " " + textje + instr + " ";
   regelnummers.addElement(new Integer(textje.length()));
   instr = filein.readLine();
   }
   filein.close();
}



Bij het parsen van elke zin:
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int start = 155; // deze staat bijvoorbeeld op 155. 
                 //Dus daar begint een nieuwe zin
boolean found = false;
for (int regelnum = 0; 
    (regelnum < regelnummers.size()) && (found == false);
    regelnum++){
  // weet iemand misschien hoe ik deze twee statements hieronder
  // netter kan doen?
  int thisline = Integer.parseInt(regelnummers.elementAt(regelnum).toString());
  int nextline = Integer.parseInt(regelnummers.elementAt(regelnum + 1).toString()) - 1;
  if (start >= thisline && start <= nextline){
     found = true;
     zin.setRegelnummer(regelnum + 1);
  }
}
found = false;


Het probleem wat ik dus heb is dat het - toch al trage - programma zo ontzettend traag wordt. Zelfs met een file die maar 5 regels groot is is hij al een seconde of 30 bezig om te parsen. En in 'the real world' zal het programma textfiles van 5K moeten parsen...

Bovendien krijg ik door de volgende regel natuurlijk altijd een IndexOutOfBounds.
Java:
1
int nextline = Integer.parseInt(regelnummers.elementAt(regelnum + 1).toString


Heeft er iemand misschien suggesties voor mijn probleem?

Verwijderd

Wat je al zeker kan doen is ipv Integer.parseInt() gewoon te casten naar (int) of meer waarschijnlijk (Integer)

Ik denk dat je gewoon teveel berekeningen doet.
Hoe kan je herkennen dat het een zin is? Met een punt? Kan een zin doorlopen op meerdere regels?

Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
try { 
    FileReader fin = new FileReader(this.locatie); 
    BufferedReader filein = new BufferedReader(fin); 
    instr = filein.readLine(); 
    int regelnummer = 1;
    String zin = "";
    while (instr != null) {
        if(instr.indexOf(".")>-1){
            //er staat een punt in
            StringTokenizer st = new StringTokenizer(instr,".");
            zin += st.nextToken();
            //regelnummer is op dit moment de regel van het laatste deel van de zin
            //als je dit van het eerste deel wil hebbne, moet je een extra teller bijhouden
            parseZin(zin,regelnummer);
            zin=""
            zin+=st.nextToken();
        }else{
            //er is geen punt gevonden, dus hij mag verder de zin "opbouwen"
            zin += instr;
            
        }
        instr = filein.readLine(); 
        regelnummer++;
    } 
    filein.close(); 
}

Verwijderd

Topicstarter
Verwijderd schreef op 15 december 2003 @ 08:19:
Wat je al zeker kan doen is ipv Integer.parseInt() gewoon te casten naar (int) of meer waarschijnlijk (Integer)

Ik denk dat je gewoon teveel berekeningen doet.
Hoe kan je herkennen dat het een zin is? Met een punt? Kan een zin doorlopen op meerdere regels?
Die zinnen zijn het probleem niet. Zoals je zelf al merkte is het erg moeilijk om te bepalen wanneer een zin is afgelopen. Niet elke "." is namelijk een eindmakeringt van een zin. Denk maar aan titels of bij afkortingen. Java heeft hier zelf al een oplossing voor gemaakt. Zo doe ik het nu:

(kort door de bocht)
Java:
1
2
3
4
5
6
7
8
9
10
11
Locale currentLocale = new Locale ("en","EN");
BreakIterator brkit = BreakIterator.getSentenceInstance(currentLocale);
brkit.setText(textje);
int start = brkit.first();
int end = brkit.next();
while (end != BreakIterator.DONE) {
    String sentence = textje.substring(start, end);
    Zin zin = new Zin(sentence, documentnummer, regelnummer);
    start = end;
    end = brkit.next();
}

  • Dash2in1
  • Registratie: November 2001
  • Laatst online: 24-05 20:08
Het zal waarschijnlijk al wat sneller gaan als je een StringBuffer gebruikt ipv een String.

  • jopie1983
  • Registratie: November 2003
  • Laatst online: 25-02-2024
Ik heb het zelf nog nooit gedaan, maar er is een klasse in de API genaamd LineNumberReader. Misschien dat je deze eens kunt proberen, kun je het lijnpositie-probleem misschien mee oplossen. Verder is het misschien eens handig om te kijken waar je code het meeste tijd verliest (bij het parsen van zinnen, of het zoeken naar regelnummer). Je kan dit gewoon eenvoudig doen door de tijd op te vragen voor een method en deze erna weer op te vragen. Heb al vaak meegemaakt dat trage gedeeltes soms op plaatsen zitten waar je het eigenlijk niet verwacht. :)