StringTokenizer des problem!!!

Résolu
youorme Messages postés 18 Date d'inscription dimanche 25 novembre 2007 Statut Membre Dernière intervention 18 avril 2010 - 2 janv. 2010 à 06:08
cheriner Messages postés 6 Date d'inscription vendredi 29 avril 2011 Statut Membre Dernière intervention 30 mai 2011 - 26 mai 2011 à 22:03
int count =0;
while(textReq.hasMoreTokens()){
String n= textReq.nextToken();

while(text.hasMoreTokens()){

if (n.equals(text.nextToken())){
count=count+1;
}}
//resultat
le nombre de similarité est :0
par contre g mis des similarité dans la requête
je sais pas c koi le problem !!!
aide

13 réponses

cs_DARKSIDIOUS Messages postés 15814 Date d'inscription jeudi 8 août 2002 Statut Membre Dernière intervention 4 mars 2013 130
2 janv. 2010 à 07:15
Salut,

Ton algorithme est un peu bancal : non seulement il ne produit pas se que tu veux, mais en plus, il est loin d'être optimisé !

Tout d'abord, pour qu'il fonctionne, il faut que tu réinitialise ton StringTokenizer dans ta première boucle, car une fois qu'il a parcourut tout ton fichier, et donc, que le text.hasMoreToken te renvoie false, il ne passera plus jamais dans la boucle... et du coup, il ne teste que le premier mot du textReq.

Ensuite, niveau optimisation, je te donne un cheminement à suivre pour bien que tu comprennes :
1/ Plutôt que de parcourir d'abord les mots entrées par l'utilisateur, puis les mots du fichier, fais l'inverse. Ca peut paraître tout bête, mais faire un tokenizer sur une dizaine de mots entrés par l'utilisateur, ca prends beaucoup moins de temps que de faire un tokenizer sur un milion de mots d'un fichier... Et donc, si l'utilisateur rentre 10 mots, au lieu de faire 10 * 1 000 000 tests longs, tu fais 1 000 000 * 10 tests courts. Niveau complexité, c'est pareil, mais niveau temps d'exécution, tu y gagne énormément !
Du coup, au lieu de :
int count =0;
while(textReq.hasMoreTokens()){
String n= textReq.nextToken();
// reinit du tokenizer de text
while(text.hasMoreTokens()){

if (n.equals(text.nextToken())){
count++;
}} 


Il vaut mieux faire :
int count =0;

while(text.hasMoreTokens()){

if (n.equals(text.nextToken())){
//réinit du tokenizer textreq

while(textReq.hasMoreTokens()){
String n= textReq.nextToken();

count++;
}} 

2/ Vu que ce sont des mots entrés par l'utilisateur, il n'y en aura pas des milions... alors pourquoi à chaque tour de boucle vouloir récupérer les mots entrés par l'utilisateur ? Stocke les dans un tableau, ce sera bien plus optimal (plus besoin de faire un tokenizer à chaque tour de boucle !) :
String[] mots = textReq.split(" ");
int count =0;
int taille = mots.length;

while(text.hasMoreTokens()){
for (int i = 0; i < taille; i++){
if (mots[i].equals(text.nextToken())){
count++;
}
} 


La complexité est la même, mais tu enlève le temps de traîtement du tokenizer sur la chaîne textreq.

3/ Pourquoi utiliser un tokenizer sur le fichier ? Tu perds énormément de temps à parcourir le fichier mot à mot !!! Là du coup, pour diminuer drastiquement la complexité, y'a une astuce toute simple : ne chercher QUE les occurences des mots à trouver, au lieu de parcourir 1 millions de mots un à un et tester à chaque fois, tu ne fait que chercher une centaine de mots (s'il y a une centaine d'occurence dans le fichier), et puis c'est tout !
Ce qui donne un truc du genre (fait de tête, à corriger très certainement) :
String[] mots = textReq.split(" ");
int count =0;
int taille = mots.length;
int index = 0;

for (int i = 0; i < taille; i++){
index = text.indexOf(mots[1]);
while(index > 0){
count++;
index=text.indexOf(mots[1]);
}
} 


Après tu aurais une autre optimisation possible : ne pas travailler avec des String mais avec un tableau de Byte, car c'est plus rapide de comparer des Byte que de comparer des String, mais là c'est du chipotage.
Bref, avec tout cà, tu vas passer d'un temps de traîtement de 10 * 1000000 du temps d'exécution du tokenizer à un temps de traîtement d'environ 10 * 100 du temps d'exécution du indexOf ! Ce qui veux dire que là où ton algorithme pouvait mettre 1 heure, la version optimisée ne prendrais plus que 1 minute...
______________________________________
DarK Sidious
3
cs_DARKSIDIOUS Messages postés 15814 Date d'inscription jeudi 8 août 2002 Statut Membre Dernière intervention 4 mars 2013 130
3 janv. 2010 à 06:22
Salut,

Oui normal, c'est une boucle infinie, il faut modifier le indexOf pour qu'il commence à la valeur de index + 1 et non à 0 à chaque fois !

Sinon, voici une version vraiment optimisée de ton code et fonctionnelle, profites-en, ca me ressemble pas de donner un code tout cuit :

Il utilise des expressions régulières pour faire le replace, et tenir compte qu'il doit s'agit d'un mot, et pas juste une chaîne au milieu d'une autre.
public static void main(String[] args){ 
  System.out.println("bonjour"); 
  readFile b =new readFile();
  String X=b.readFile();
  String replaceChaine = "(un )|(est )|( et)|(une )|(la )|(les )|(le )|(l')|(de )|(des )|(d' )|(pour )|(comme )|(ou )|(dans )";
         
  String S = X.toLowerCase().replaceAll(replaceChaine,"");

  System.out.println(S);
  System.out.println("entrer votre requete :");
  String req=lire.S();

  String reqElag=req.toLowerCase().replaceAll(replaceChaine,"");
  System.out.println(reqElag);
  String[] mots = reqElag.split(" ");
  int count =0;
  int taille = mots.length;
  int index = 0;

  for (int i = 0; i < taille; i++){
    index = S.indexOf(mots[i]);
    while(index > 0){
      count++;
      index=S.indexOf(mots[i], index + 1);
    }
  } 
  System.out.println ("le nombre de similariter est :"+count);	
}


Non seulement ce code est plus lisible, plus compréhensible, et plus facilement maintenable, mais il est aussi bien plus rapide.
______________________________________
DarK Sidious
3
youorme Messages postés 18 Date d'inscription dimanche 25 novembre 2007 Statut Membre Dernière intervention 18 avril 2010
2 janv. 2010 à 06:10
textReq c est une requete entrer au clavier par l'utilisateur
text c est un fichier .txt lit par par la methode readFile que g implementer c tous pour le moment
0
youorme Messages postés 18 Date d'inscription dimanche 25 novembre 2007 Statut Membre Dernière intervention 18 avril 2010
2 janv. 2010 à 17:57
package Indexation;

import java.util.StringTokenizer;

public class test {
public static void main(String[] args){ 
System.out.println("bonjour"); 
readFile b =new readFile();
String X=b.readFile();
StringTokenizer text= new StringTokenizer(X);
String S="";
System.out.println("Nombre de mots :"+ text.countTokens());
while(text.hasMoreTokens()){
 String W= text.nextToken();
if(!((W.equals("un"))||(W.equals("est"))||(W.equals("et"))||(W.equals("une"))||(W.equals("la"))||(W.equals("les"))
||(W.equals("le"))||(W.equals("l'"))||(W.equals("de"))||(W.equals("des"))||(W.equals("d'"))||(W.equals("pour"))
||(W.equals("comme"))||(W.equals("ou"))||(W.equals("dans")))){

S= S +" "+ W;
}
}
System.out.println(S);
System.out.println("entrer votre requete :");
String req=lire.S();
StringTokenizer textReq= new StringTokenizer(req);
String reqElag="";
System.out.println("Nombre de mots :"+ textReq.countTokens());
while(textReq.hasMoreTokens()){
String w= textReq.nextToken();
if(!((w.equals("un"))||(w.equals("est"))||(w.equals("et"))||(w.equals("une"))||(w.equals("la"))||(w.equals("les"))
||(w.equals("le"))||(w.equals("l'"))||(w.equals("de"))||(w.equals("des"))||(w.equals("d'"))||(w.equals("pour"))
||(w.equals("comme"))||(w.equals("ou"))||(w.equals("dans")))){

reqElag+=" "+ w;

}
}System.out.println(reqElag);
String[] mots = reqElag.split(" ");
int count =0;
int taille = mots.length;
int index = 0;

for (int i = 0; i < taille; i++){
index = S.indexOf(mots[1]);
while(index > 0){
count++;
index=S.indexOf(mots[1]);
}
} System.out.println ("le nombre de similariter est :"+count);	

}


}

// laffichge ne marche po
et g pa compris pk t'as mis mots[1] et non pas mot[i]
merci
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
youorme Messages postés 18 Date d'inscription dimanche 25 novembre 2007 Statut Membre Dernière intervention 18 avril 2010
2 janv. 2010 à 17:58
en faite il deux autre classe readFile pour lire un fichier text
lire pour la lecture clavier
0
cs_DARKSIDIOUS Messages postés 15814 Date d'inscription jeudi 8 août 2002 Statut Membre Dernière intervention 4 mars 2013 130
2 janv. 2010 à 18:03
Salut,

Oui c'est une erreur de ma part, il faut bien mettre mots[i] au lieu de mots[1]
______________________________________
DarK Sidious
0
youorme Messages postés 18 Date d'inscription dimanche 25 novembre 2007 Statut Membre Dernière intervention 18 avril 2010
2 janv. 2010 à 18:07
alors pk l'affichage ne marche po stp??
0
cs_DARKSIDIOUS Messages postés 15814 Date d'inscription jeudi 8 août 2002 Statut Membre Dernière intervention 4 mars 2013 130
2 janv. 2010 à 18:20
Salut,

Tu aimes faire les trucs non optimisés apparement :)

Pour remplacer les mots que tu ne veux pas tester, il te suffit de faire des replaces, plutôt que de passer par un StringTokenizer (encore !) :

Au lieu de :
while(text.hasMoreTokens()){
 String W= text.nextToken();
if(!((W.equals("un"))||(W.equals("est"))||(W.equals("et"))||(W.equals("une"))||(W.equals("la"))||(W.equals("les"))
||(W.equals("le"))||(W.equals("l'"))||(W.equals("de"))||(W.equals("des"))||(W.equals("d'"))||(W.equals("pour"))
||(W.equals("comme"))||(W.equals("ou"))||(W.equals("dans")))){

S= S +" "+ W;
}
}


mets plutôt :
String S = X.replaceAll("un", "");
String S = S.replaceAll("est", "");
String S = S.replaceAll("et", ""); 
// etc.


idem pour le texte de l'utilisateur

Après, qu'est-ce que tu veux dire par "l'affichage ne marche pas" ? Ca t'affiche quoi ? 0 ?


Sinon, evite le langage SMS, tu as un clavier complet, alors profites-en pour écrire normalement, c'est chiant à lire !
______________________________________
DarK Sidious
0
youorme Messages postés 18 Date d'inscription dimanche 25 novembre 2007 Statut Membre Dernière intervention 18 avril 2010
3 janv. 2010 à 00:30
ok dsl
l'affichage ne marche c est a dire le System.out.println ("le nombre de similariter est :"+count);
n'affiche rien :)
et pour les chose non optimiser je suit encore débutant je cherche un prog qui marche pour le moment même mes professeur ne vont pas tenir compte de l'optimisation
mais ca n'empêche pas de te dire merci pour tes consigne
0
youorme Messages postés 18 Date d'inscription dimanche 25 novembre 2007 Statut Membre Dernière intervention 18 avril 2010
3 janv. 2010 à 00:50
en plus si j'utilise la fonction .replaceAll
elle va remplacer meme le sous cahine indiquer dans une chaine donner comme par exemple si je veux eliminer le mot "le"
il va l'eliminer de la chane "exemple" ce qui devient "exemp" ;)
et je ve pa que ca se produit
0
youorme Messages postés 18 Date d'inscription dimanche 25 novembre 2007 Statut Membre Dernière intervention 18 avril 2010
4 janv. 2010 à 02:39
ok merci bien de votre aide ;)
mais dans replacechaine() il faut ke avant et apres le mots mettre un espace
:)
0
cheriner Messages postés 6 Date d'inscription vendredi 29 avril 2011 Statut Membre Dernière intervention 30 mai 2011
26 mai 2011 à 11:19
[^^happy13]
0
cheriner Messages postés 6 Date d'inscription vendredi 29 avril 2011 Statut Membre Dernière intervention 30 mai 2011
26 mai 2011 à 22:03
je suis recherch a un algorithme pour calcule la similarite entre deux schema xml
0
Rejoignez-nous