Black Friday = Pricewatch Bekijk onze selectie van de beste Black Friday-deals en voorkom een miskoop.
Toon posts:

[Java] Zoeken naar woord in String[ ][ ]

Pagina: 1
Acties:

Verwijderd

Topicstarter
Hoi,

Voor school heb ik een opdracht om bij verschillende (300K) steden, die uit een DB komen een lengte en een breedte graad te zoeken. Deze staan allemaal in een .csv bestand, dat op de volgende manier is ingericht:
code:
1
2
naam_stad_1,een_alias__stad_1, een_alias_stad_1, .... , laatste_alias_stad_1|lengtegraad1|breedtegraad1
naam_stad_2,een_alias__stad_2, een_alias_stad_2, .... , laatste_alias_stad_2|lengtegraad2|breedtegraad2. ETC.

Ik ben dus in de eerste plaats geïnterreseerd, in wanneer een een stad naam invoer (bijvoorbeeld Londen) of hij voorkomt in een van records, onder een van zijn aliassen. Wat ik dus heb gedaan is een grote 2D array maken, en daar alle records met zijn aliassen in gegooid. Ziet er ongeveer zo uit:
code:
1
2
3
4
5
6
7
8
alias = new String[148000][10]

alias[0][0] = "Den Haag";
alias[0][1] = "'s Schravenhage";
alias[0][2] = "Den_Haag";
alias[1][0] = "Katwijk";
alias[1][1] = "Katwyk";
etc.

Let op dat de array niet voledig gevuld is. Alle 148000 steden zijn ongeveer ingevuld, maar niet allemaal beschikken ze over 10 aliassen.
Dit gaat goed. Nu wil ik erin zoeken. Hier heb ik de volgende functie voor geschreven:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public String[] getLonLat( String cityName){
        // alias is bij het uitvoeren van deze functie al geinitialiseerd.
    lonLat = new String[3];
    for( int i = 0; i < alias.length; i++ ){
        for( int j = 0; j < alias[i].length; j++ ){
            if( cityName.equals(alias[i][j])){
                lonLat[0] = alias[i][1];
                lonLat[1] = data[1];
                lonLat[2] = data[2];
                j += alias[i].length;
                i += alias.length;
            }
        }
    }
        
    return lonLat;
}

Dit gaat bij het eerste record al fout. Ten minste, lange tijd gaat het goed (tot j =~ 4800, en i = 0, wanneer hij opschuift naar 1 gaat dit fout) en dan geeft hij een error, namelijk
code:
1
java.lang.ArrayIndexOutOfBoundsException: 152870


Deze error betekend, zover ik weet, dat hij een array cel probeert uit te lezen die niet is ingevuld. Dit is ten eerste onmogelijk, omdat de stelling i < alias[i].lenght ervoor zorgt dat hij nooit zover kan komen en ten tweede omdat wanneer ik een aantal System.out.println()'s doe, deze gewoon waardes aangeven waaruit nergens blijkt dat cel alias[4800][1] geen waarde heeft. Sterker nog, zelfs [4800][2] zou een waarde moeten hebben en wanneer ik deze afzonderlijk buiten de for loops probeer op te vragen, geeft dit geen problemen.

Iemand enig idee hoe dit kan?

Jan

  • chris
  • Registratie: September 2001
  • Laatst online: 11-03-2022
Ik heb het niet getest, maar ik gok dat je de volgende twee regels weg moet halen:
Java:
1
2
                j += alias[i].length;
                i += alias.length;

  • Not Pingu
  • Registratie: November 2001
  • Laatst online: 21-10 20:21

Not Pingu

Dumbass ex machina

Kun je in Java niet gewoon jagged multidimensional arrays maken? Dus niet voor elke [] een [][10] aanmaken maar gewoon arrays die net zo groot zijn als het aantal aliasen?

Certified smart block developer op de agile darkchain stack. PM voor info.


Verwijderd

Topicstarter
chris schreef op donderdag 16 oktober 2008 @ 22:15:
Ik heb het niet getest, maar ik gok dat je de volgende twee regels weg moet halen:
Java:
1
2
                j += alias[i].length;
                i += alias.length;
Klopt helemaal!
Ik had ze er eigenlijk in gestopt, om ervoor te zorgen dat wanneer er een match gevonden was, hij niet de rest van de loop zou hoeven doorlopen. Dit was alleen een grote fout, want iedere keer gaat hij nu in de for loop over zijn hachel, omdat het aantal wat hij zoekt te groot is.

Heel erg bedankt!

  • YopY
  • Registratie: September 2003
  • Laatst online: 06-11 13:47
Je zou ook een class Stad kunnen maken waar een List met aliassen in staat en de lengte / breedtegraad, dan ben je gelijk van het hele probleem van array indices af. Is misschien niet zo snel, maar wel 'netter' (iets wat overigens persoonlijk is).

Ook is het over het algemeen af te raden om een index van een for loop ( i en j in dit geval) te beinvloeden binnen de loop.

[ Voor 20% gewijzigd door YopY op 16-10-2008 22:33 ]


  • LinuX-TUX
  • Registratie: December 2003
  • Laatst online: 17-10 10:30
code:
1
lonLat[0] = alias[i][1];


Zomaar hoor, maar een array begint toch bij 0 en niet een statische 1 die je daar invult :?

Daarnaast, ik zie in je vorige topics dat je Eclipse gebruikt, wat is er mis met die debugger? Handig man, zou me er eens in verdiepen ;)
Er van uitgaande dat je in lonLat[0] de naam van de stad invult, krijg je een index out of bounds exceptie bij een stad die geen Aliassen in de lijst heeft :Y)

[ Voor 25% gewijzigd door LinuX-TUX op 16-10-2008 22:40 ]


  • merlijn85
  • Registratie: Juli 2007
  • Laatst online: 29-12-2022
Verwijderd schreef op donderdag 16 oktober 2008 @ 22:32:
[...]

Klopt helemaal!
Ik had ze er eigenlijk in gestopt, om ervoor te zorgen dat wanneer er een match gevonden was, hij niet de rest van de loop zou hoeven doorlopen. Dit was alleen een grote fout, want iedere keer gaat hij nu in de for loop over zijn hachel, omdat het aantal wat hij zoekt te groot is.

Heel erg bedankt!
Om dat te doen zet je daar het return commando, en helemaal onderaan een return null; om te zorgen dat die nog iets returned wanneer die geen match kan vinden.

Verwijderd

merlijn85 schreef op donderdag 16 oktober 2008 @ 22:38:
[...]


Om dat te doen zet je daar het return commando, en helemaal onderaan een return null; om te zorgen dat die nog iets returned wanneer die geen match kan vinden.
Of je if statement body afsluiten met een break...

  • Jaap-Jan
  • Registratie: Februari 2001
  • Laatst online: 21:00
In plaats van een array, zou ik zoeken naar andere datastructuren.

Ik zou als ik jou was eens kijken naar het Java collections framework (onder java.util Vooral HashMap. In plaats van zelf door een array te moeten zoeken, wat O(N) is, kun je gewoon zoeken in de hashmap, wat O(1) is. Ook het dingen toevoegen aan de hashmap is O(1), net zoals een array.

Voor je aliassen kun je dan een hashmap maken, met als key de alias en als value de 'echte' naam. Voor de mapping van naam aan een set hoogte- en breedtegraden, zou ik voor die laatste een klasse maken die beide bevat en dan een hashmap maken met als key de naam en als value die klasse die hoogte- en breedtegraad bevat.

offtopic:
Het is niet "'s Schravenhage", maar "'s-Gravenhage". De betekenis is 'des gravenhage' --> de haag van de graaf --> Den Haag ;)

[ Voor 17% gewijzigd door Jaap-Jan op 17-10-2008 11:26 ]

| Last.fm | "Mr Bent liked counting. You could trust numbers, except perhaps for pi, but he was working on that in his spare time and it was bound to give in sooner or later." -Terry Pratchett


  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Ik zou inderdaad ook iets met een Dictionary of Hashmap doen.

Je maakt bijvoorbeeld bij het uitlezen een Stad object aan met zijn naam en al zijn aliassen, daarna voeg je in een Hashmap alle alliasen als key toe met als value het stad object.

Je zou alleen mischien conflicten kunnen krijgen als aliassen dubbel voorkomen, maar dan zou je eventueel een lijst van steden bij een alias bij kunnen houden.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


  • Jaap-Jan
  • Registratie: Februari 2001
  • Laatst online: 21:00
rwb schreef op vrijdag 17 oktober 2008 @ 11:54:
(..)

Je maakt bijvoorbeeld bij het uitlezen een Stad object aan met zijn naam en al zijn aliassen, daarna voeg je in een Hashmap alle alliasen als key toe met als value het stad object.
Oeps, da's een veel beter idee, al hoef je bij een stad in principe zijn aliassen niet bij te houden in het object zelf. :)
Je zou alleen mischien conflicten kunnen krijgen als aliassen dubbel voorkomen, maar dan zou je eventueel een lijst van steden bij een alias bij kunnen houden.
Dat probleem zou je ook hebben bij een array. De eerste stad van de alias die matcht zou je dan terugkrijgen.

Maar sowieso is het lastig omgaan met steden met gelijke aliassen. Je kunt niet bepalen welke je moet hebben. Dus eigenlijk moet je ervan uitgaan dat je geen dubbele hebt. En als je dat bij het toevoegen zeker wilt weten, doe dan voor het toevoegen eerst containsKey() zodat je een melding kan geven als een alias al eerder is toegevoegd. :)

| Last.fm | "Mr Bent liked counting. You could trust numbers, except perhaps for pi, but he was working on that in his spare time and it was bound to give in sooner or later." -Terry Pratchett


  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Jaap-Jan schreef op vrijdag 17 oktober 2008 @ 12:10:
[...]

Oeps, da's een veel beter idee, al hoef je bij een stad in principe zijn aliassen niet bij te houden in het object zelf. :)
Het ligt er natuurlijk aan wat je wilt met de resultaten, mischien wil je aan de hand van een alias wel zoeken op alle verschillende aliassen die voor een stad bestaan
[...]
Dat probleem zou je ook hebben bij een array. De eerste stad van de alias die matcht zou je dan terugkrijgen.

Maar sowieso is het lastig omgaan met steden met gelijke aliassen. Je kunt niet bepalen welke je moet hebben. Dus eigenlijk moet je ervan uitgaan dat je geen dubbele hebt. En als je dat bij het toevoegen zeker wilt weten, doe dan voor het toevoegen eerst containsKey() zodat je een melding kan geven als een alias al eerder is toegevoegd. :)
Ook dit ligt er weer aan wat je er precies mee wilt doen, mischien wil je de gebruiker in het geval van een conflict wel de keuze geven aan de hand van de gevonden mognelijkheden.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


  • Treggats
  • Registratie: April 2005
  • Laatst online: 15-01-2024

Treggats

Koe'tje

Not Pingu schreef op donderdag 16 oktober 2008 @ 22:29:
Kun je in Java niet gewoon jagged multidimensional arrays maken? Dus niet voor elke [] een []\[10] aanmaken maar gewoon arrays die net zo groot zijn als het aantal aliasen?
Volgens mij was dat dan een ArrayList, deze groeit mee met het aantal aliassen

  • Jaap-Jan
  • Registratie: Februari 2001
  • Laatst online: 21:00
Treggats schreef op vrijdag 17 oktober 2008 @ 17:46:
[...]

Volgens mij was dat dan een ArrayList, deze groeit mee met het aantal aliassen
Je hebt wel gelijk, hoor, dat een ArrayList meegroeit, maar hij bedoeld wat anders.

Als een array jagged kan zijn betekent dat, bij een array[x][y] voor elke x, de lengte van y kan verschillen. En Java heeft inderdaad jagged arrays. :)

| Last.fm | "Mr Bent liked counting. You could trust numbers, except perhaps for pi, but he was working on that in his spare time and it was bound to give in sooner or later." -Terry Pratchett


  • LinuX-TUX
  • Registratie: December 2003
  • Laatst online: 17-10 10:30
Beste Zwaaikom,

heb je het probleem inmiddels al getackled? Zo nee, zou je het dan met je mede-tweakers willen delen om in te zien? (als het toch een schoolopdracht is, zie ik het probleem niet :Y) ... en maak je geen zorgen, ik ben al afgestudeerd, op een school aan de andere kant van het land ;) )

Cheers :Y)
Pagina: 1