2010-09-05 6 views
2

Je compare des sous-chaînes dans deux gros fichiers texte. Très simple, tokenizing en deux conteneurs jetons, en comparant avec 2 pour les boucles. Les performances sont désastreuses! Est-ce que quelqu'un a un conseil ou une idée pour améliorer la performance?Comparaison de chaînes Java

for (int s = 0; s < txtA.TokenContainer.size(); s++) { 
    String strTxtA = txtA.getSubStr(s); 
    strLengthA = txtA.getNumToken(s); 

    if (strLengthA >= dp.getMinStrLength()) { 
     int tokenFileB = 1; 

     for (int t = 0; t < txtB.TokenContainer.size(); t++) { 
      String strTxtB = txtB.getSubStr(t); 
      strLengthB = txtB.getNumToken(t); 

      if (strTxtA.equalsIgnoreCase(strTxtB)) { 
       try { 
        subStrTemp = new SubStrTemp(
         txtA.ID, txtB.ID, tokenFileA, tokenFileB, 
         (tokenFileA + strLengthA - 1), 
         (tokenFileB + strLengthB - 1)); 

        if (subStrContainer.contains(subStrTemp) == false) { 
         subStrContainer.addElement(subStrTemp); 
        } 
       } catch (Exception ex) { 
        logger.error("error"); 
       } 
      } 
      tokenFileB += strLengthB; 
     } 
     tokenFileA += strLengthA; 
    } 
} 

En général, mon code de lecture deux grandes chaînes avec Java Tokonizer dans des conteneurs A et B. Et puis essayer de comparer substrings.Possision de Substrgs qui sont en vigueur dans les deux chaînes pour stocker dans un vecteur. Mais la performance est horrible, aussi ne savent pas vraiment comment le résoudre avec HashMap.

+2

Pouvez-vous décrire avec des mots ou avec un exemple ce que votre code ne ? –

Répondre

7

Votre problème principal est que vous passez par tout txtB pour chaque jeton dans txtA.

Vous devez stocker des informations sur le jeton de txtA (dans un HashMap par exemple) puis dans une seconde boucle (mais pas une imbriquée), vous comparez les chaînes avec la chaîne existante dans la carte.


Sur le même sujet:

+0

Merci Colin HEBERT, "imbriqué" -> "pour() {pour() {}}," "pas imbriqué" -> "pour() {}, pour() {}" à droite? Hashmap J'ai vraiment peur de .. jamais codé le code auparavant. Depuis que je sais dans HashMap je dois utiliser HashSet et ici les jetons redondants sont supprimés !? Ok, je n'en ai pas besoin, mais j'ai besoin de leurs positions. Pouvez-vous me dire si je peux stocker et récupérer des positions de jetons avec HashMap? – jackdaniels

+0

C'est exactement cela pour l'imbriqué/non imbriqué. Si vous voulez garder les positions, vous pouvez faire ceci 'HashMap >' de sorte que vous pouvez avoir pour chaque mot une liste de sa position. Ou mieux, au lieu d'Integer votre propre structure avec le nom de fichier, la position et d'autres informations. –

+0

Huh ... pense que j'ai implémenté ta suggestion Colin. Mais en quelque sorte incapable d'obtenir des paramètres Hashmap .. Pouvez-vous jeter un oeil pls, le code de programmation est ici jackdaniels

2

Vous effectuez une jointure avec des boucles imbriquées? Oui, c'est O (n^2). Que diriez-vous de faire une jointure de hachage à la place? C'est-à-dire, créer une carte à partir de strText (en minuscules) vers t et faire des recherches avec cette carte plutôt que d'itérer sur le conteneur de jetons?

+0

Bonjour Meriton, Merci de votre aide. Oui, je l'ai fait, mais je n'en veux pas plus. La performance était également bonne avec les petites chaînes, une autre raison avec les boucles imbriquées que j'étais capable de stocker des strPositions (de mêmes sous-chaînes) (presque) triées dans un vecteur. – jackdaniels

+0

Oui, je l'ai déjà il n'y a pas de moyen de Hashing et de cartographie .. Je dois l'apprendre .. :-(Pouvez-vous me dire pls, comment puis-je faire un HashJoin en Java? Je n'ai pas trouvé d'exemple Java - en particulier HashJoin dans google ... Et si HashJoin comment puis-je stocker subStr-positons, ceux-ci sont nécessaires pour stocker – jackdaniels

+0

S'il vous plaît dites-moi aussi, pourquoi il est nécessaire de minuscules String? Comment puis-je créer une "carte de (minuscules) strText à t « ? Cette phrase, je ne l'ai pas vraiment compris .. Merci à l'avance. S'il vous plaît me dire aussi, pourquoi il est nécessaire de minuscules cordes? Comment puis-je créer une » carte de (en minuscules) strText à t "?Cette phrase je n'ai pas vraiment entrepris .. – jackdaniels

0

Placez les jetons de fileA dans une structure de données trie. Ensuite, quand tokenising fileB vous pouvez vérifier assez rapidement si ces jetons sont dans le trie. Quelques commentaires de code aideraient.

+0

Merci James, quelle structure de données suggérez-vous d'utiliser? – jackdaniels

+0

Plus de commentaires, avec plaisir .. Je suis en train de lire des fichiers txt avec l'aide de java tokenizer dans une chaîne, puis en essayant de rechercher la sous-chaîne de DocA dans DocB. Faire cela dans 2 cas. Le premier cas, la longueur de la sous-chaîne, est constat, le second cas la longueur de la sous-chaîne varie, pour cette raison j'ai ajouté "if (strLengthA> = dp.getMinStrLength())" pour réduire l'itération pour les sous-chaînes très courtes. – jackdaniels

+0

A Trie: http://en.wikipedia.org/wiki/Trie. – James

0

A dit, ceci est une question de la complexité et vous êtes algorithme court dans O (n^2) au lieu de O (n) en utilisant le hachage.

Pour la seconde améliorations d'ordre essayer d'appeler moins de fonctions, par exemple, vous pouvez obtenir la taille une fois

sizeB = txtB.TokenContainer.size();

Depeneds sur la taille, vous pouvez appeler le récipient une fois pour obtenir un tableau de chaînes pour sauver la getStr ....

Roni

+0

Merci Roni, je ne savais pas si appeler des fonctions prendrait des performances. Mais bien sûr, en particulier "txtB.TokenContainer.size();" programmer appels tous les n fois, absolument inutile. – jackdaniels