2015-11-01 1 views
0

Considérant que nous avons un String qui contient trois mots, par exemple, "kids story book" où nous avons ajouté chacun de ces mots dans un HashMap<String, Integer> tandis que la partie String contient le mot et la partie Integer contient la position de mot dans la chaîne, à savoir, 1, 2 et 3. Supposons également qu'il existe un autre type de HashMap qui est le champ par un sérieux de mots groupés. Considérez que chaque groupe de mots a une valeur entière commune en tant qu'ID qui indique qu'ils appartiennent ensemble. Mon but est de regarder dans la seconde HashMap afin de trouver toutes les chaînes qui contient soit kids, story ou book, puis renvoyer le mot avec son ID entier unique. Voici mon code pour le faire:problème avec contains() pour correspondre à deux chaînes

 String keyword="kids story book"; 
     static HashMap<String, Integer> tempp = new HashMap<>(); 
     static HashMap<String, Integer> stringToint = new HashMap<>(); 

       //File is .txt file which contains some characters at each line 
       FileOutputStream Fcategorize=new FileOutputStream(File,true); 

      FileReader inputFile = new FileReader(File); 

      BufferedReader bufferReader = new BufferedReader(inputFile); 

String line = bufferReader.readLine(); 


     for(int i = 0; line != null; i++){ 
     if(header(i).equals(line)){ 
      while((line = bufferReader.readLine()) != null && ! Footer(i).equals(line)) 
       { 


stringToint.put(line, i); 
} 
       } 

     } 



    StringTokenizer start=new StringTokenizer(keyword); 

    for(int i=-1; i<=start.countTokens();i++) 
    { 
     String temp=start.nextToken(); 
     tempp.put(temp, i); 
    } 

    Set<String> fkeys = stringToint.keySet(); 
    Iterator<String> fit = fkeys.iterator(); 


    Set<String> Lkeys =tempp.keySet(); 
    Iterator<String> sit = Lkeys.iterator(); 


    for(int i=0 ; i<tempp.size() ; i++) 
    { 
    nextToken=sit.next(); 
    while (fit.hasNext()){ 
        String featurename = fit.next(); 

       if(featurename.contains(nextToken)) 
       { 

       //Do something 
       } 

      } 

    } 

Il y a trois problèmes: Tout d'abord, la première HashMap contient bien tous les trois mots, mais si j'utilise la console pour imprimer les résultats, il imprime uniquement la mise en correspondance pour le premier élément de HashMap et pas tous les trois (alors qu'il y a d'autres correspondances pour chacun des trois mots). Deuxièmement, comme il est évident dans le code, j'ai commencé la boucle de i=-1 et c'est parce que si j'utilise i=0 il n'ajoutera pas tous les trois caractères au HashMap et dans ce cas, l'ordre des mots dans la chaîne ne sera pas le même que l'ordre d'entre eux dans le HashMap et enfin, même pour les articles dans la première position du HashMap, il ne retourne même pas tout le match, utilisé par . J'ai vérifié manuellement et j'ai découvert qu'il y avait plus de résultats à retourner pendant que ça n'arrivait pas.

+0

Veuillez fournir un petit exemple exécutable de votre problème qui contient du code sur la façon dont les deux cartes sont remplies. – Tom

+0

@Tom Et maintenant? – lonesome

Répondre

1

Le troisième problème est que vous ne réinitialisez pas l'itérateur fit à chaque recherche de mot (dans votre code, réinitialiser signifie initialiser un nouveau). En fait, vous devez l'initialiser à chaque fois dans votre boucle for

for(int i=0 ; i<tempp.size() ; i++) 
{ 
    nextToken=sit.next(); 
    fit = fkeys.iterator(); 
    while (fit.hasNext()){ 
     .... 
+0

Jolly Good! c'était vrai! – lonesome

+0

Mais je me demande pourquoi 'Iterator fit = fkeys.iterator()' est inutile? Je veux dire que si j'enlève '= fkeys.iterator()', cela fonctionne toujours correctement. De plus, l'EDI affiche aussi une notification de "Affectation inutilisée". – lonesome

+0

Oui, c'est parce qu'il n'est pas utilisé car vous le réinitialisez à l'intérieur pour la boucle. Déclarez simplement la variable Iterator ; ou définissez-le à null :: Iterator fit = null; –

1

Pour résoudre votre deuxième problème: vous devez stocker la valeur de start.countTokens(); dans une autre variable d'abord, au lieu de l'évaluer dans chaque boucle. Parce que chaque fois que vous appelez start.nextToken(), start.countTokens() réduit de 1.

Modifier: vous pouvez utiliser LinkedHashMap pour maintenir l'ordre des entrées de la façon dont ils sont ajoutés à la carte.

HashMap<String, Integer> tempp = new LinkedHashMap<>(); // use LinkedHashMap to maintain order 

    String keyword = "kids story book"; 
    StringTokenizer start = new StringTokenizer(keyword); 
    int count = start.countTokens(); // save it to another variable 

    for (int i = 0; i < count; i++) { 
     String temp = start.nextToken(); 
     tempp.put(temp, i); 
    } 

    for (Map.Entry entry : tempp.entrySet()) { 
     System.out.println(entry.getKey() + ", " + entry.getValue()); 
    } 
    // gives you 
    // kids, 0 
    // story, 1 
    // book, 2 
+0

Mais l'ordre est toujours un problème. le dernier est à la première place. bien qu'ayant 'i = 2' mais apparaît au début du' HashMap'. pourquoi est-ce si? L'ordre est comme '2',' 0' et ensuite '1' – lonesome

+0

@lonesome HashMap ne maintient pas l'ordre des entrées de la façon dont elles sont ajoutées à la carte, si vous voulez maintenir la commande. Utilisez LinkedHashMap. J'ai mis à jour ma réponse – Bon

+0

compris, merci. obtenir mon +1 alors que je n'ai toujours pas résolu tous les problèmes en une seule réponse. – lonesome