[php]une chaine de caractère égal à une autre? - modification (dernier message!)

est-ce que mon code me permet d’effectuer ce que je veux, c’est à dire de savoir si 2mots son pareil, et ainsi compter le nombre de répétition d’un même mot pour chaque mot :


	$les_mots = split_words(strtolower($contenu1));
	$nb_mots = count($les_mots);
	$i = 0;
	$poids[$i] = 0;
	echo $i;
	echo "<br>".$poids[$i];
	echo "<br>".$les_mots[$i];	
	for($i=0;$i<$nb_mots;$i++)
	{	
  if ($les_mots[$i]!="  ")
  {
  	$j = 0;
  	echo $les_mots[$j];
  	for ($j=0;$j<$nb_mots;$j++)
  	{
    if ($les_mots[$i]==$les_mots[$j])
    {
    	$poids[$i]=$poids[$i]+1;
    	$les_mots[$j]=" ";
    }
    else
    {
    	echo "probleme";
    }
  	$j=$j+1;
  	}  	
  }
	$i=$i+1;
	}

surtout si

 
if ($les_mots[$i]==$les_mots[$j])

est possible, parce que pour $i = 0 et $j=0, j’ai bien le même mot (logique c’est le même contenu) mais au lieu de rentrer dans mon alors, j’ai problemeproblemeprobleme 36.000fois.
Je crois donc que j’ai besoin d’aide s’il vous plait!!!!!!!!!!!!!!!!!!!

Bonjour,
il ne faut pas faire démarrer j à 0 mais à i+1, sinon, tu va effacer la première occurence de tous les mots.

autres choses aussi, j’ai une table mots_vide, et dans mon tableau


$les_mots = split_words($contenu1);
$nb_mots = count($les_mots);

il ne faut que qu’apparaissent ces mots-vides!!! Personnellement, je ne vois pas du tout comment faire!! il faudrait que j’utilise une requête du genre NOT IN, mais cela devrait dire que je dois au prélable, enregistré tous mes mots dans ma base, enfin tous les mots de mon contenu.mot par mot!!!
Merci d’avance pour l’aide que vous m’apporterez!!

Là je dois avouer que je ne comprend pas, qu’entend tu par “mot vide” et par “NOT IN”? ta double boucle sert déjà à détecter les mots égaux entre eux.

Heu juste comme ça :

$les_mots = split_words(strtolower($contenu1));
$poids = array();

foreach ($les_mots as $m) {
  $p =& $poids[$m];
  if (!isset($p)) $p = 1;
  else ++$p;
}

var_dump($poids);

Ce qui revient au même tu me diras.

les mots vides sont les mots rentrés dans une table (paramètre) de ma base, ce sont les mots du genre "a, la, le, il, elle, on, ont, à, et, les, …", les mots inutiles dans une recherche mot par mot
par exemple on cherche : la boite de pandore
et la recherche mot par mot selectionnera boite et pandore…

et "NOT IN" du genre
INSERT INTO MOT (mot) values ($les_mots[$i])
WHERE $les_mots[$i] NOT IN (SELECT mot_vide FROM mots_vide)

ma double boucle recherche les mots égaux, cependant, j’obtiens "problemeprobleme … ", ce qui veut dire que $les_mots[$i]!=$les_mots[$j], alors que quand je teste sur 2mots identiques, ça ne marche pas…

changement du code :


$contenu1 = strtolower($contenu1);
  $les_mots = split_words($contenu1); //tableau mot par mot
  $nb_mots = count($les_mots);
  $i = 0;
  sort($les_mots); //tableau des mots par ordre alphabétique
  for ($i=0;$i<$nb_mots;$i++)
  {
  	$poids=1;
  	while ($les_mots[$i]==$les_mots[$i+1])
  	{
    $poids=$poids+1;
    $i=$i+1;
  	}	
  	echo "<br>".$poids."\n";
  	echo $les_mots[$i]."\n";
  	$req1="INSERT INTO mot (Mot, Poids) VALUES ( '".mysql_real_escape_string($les_mots[$i])."','".mysql_real_escape_string($poids)."') WHERE 'mysql_real_escape_string($les_mots[$i])' NOT IN (SELECT mot_vide FROM mots_vide)";
  	$result1=mysql_query($req1,$CONNEXION);
  	if($result1)
  	{
    echo "<br>enregistrement pris en compte";
  	}
  	else
  	{
    echo "<br>recommencer, erreur dans l' enregistrement";
  	}
  }

et là, la question qui se pose, c’est est-ce que ma requête est bonne???(avec le not in) parce que sans ça, ça marche sans probleme!!! mais vu que je ne veux pas que ma table enregistre les mots qui sont déjà dans la table des mots vide!!! et je ne vois pas comment faire autrement!!!

Bonjour,
tu ne peux pas mettre de whre dans un insert, c’est uniquement sur un select.
mais là, le plus simple c’est de tester avant l’insertion si ton mot fait partie de la liste des vides, en PHP, en mettant la liste des mots vides dans un tableau.

note: Sans-Nom connait bien mieux le PHP que moi, et son code a l’air plutôt bien, ta nouvelle version a l’air d’avoir un bug:
$les_mots[$i]==$les_mots[$i+1]

là tu ne teste que 2 mots consécutifs, il fallait bien garder un 2ème boucle sur $j, ou passer à la méthode sans-nom.
:slight_smile:

ok ok, pour l’idée de mettre mes mots-vide dans un tableau, mais euh, de SQL à PHP, on fait comment??? :confused:
Là, j’avoue que j’ai un gros trou!!!
si je fais mysql_fect_array => ça m’affiche tout, il n’y a pas moyen de faire ligne par ligne, pour pouvoir faire une boucle???et vérifier pour chaque mot s’il correspond au mot vide
un truc comme :


for ($i=0;$i<$nb_mots;$i++)
  {
  	$poids=1;
  	while ($les_mots[$i]==$les_mots[$i+1])
  	{
    $poids=$poids+1;
    $i=$i+1;
  	}	
  	echo "<br>".$poids."\n";
  	echo $les_mots[$i]."\n";
  	while($tuple=mysql_fetch_array($CurseurMV)) 
  	{
    if ($tuple['mot_vide']!=$les_mots[$i])
    {
    	$req1="INSERT INTO mot (Mot, Poids) VALUES ( '".mysql_real_escape_string($les_mots[$i])."','".mysql_real_escape_string($poids)."')";
    	$result1=mysql_query($req1,$CONNEXION);
    	if($result1)
    	{
      echo "<br>enregistrement pris en compte";
    	}
    	else
    	{
      echo "<br>recommencer, erreur dans l' enregistrement";
    	}
    }
  	}	

mais bon, là ça m’enregistre le premier $les_mots[$i] autant de foisqu’il y a de mot vide!!!! (je ne sais pas si vous voyez ce que je veux dire en gros!!!)

re-modification


$contenu1 = strtolower($contenu1);
  $les_mots = split_words($contenu1); //tableau mot par mot
  $nb_mots = count($les_mots);
  $i = 0;
  sort($les_mots); //tableau des mots par ordre alphabétique
  for ($i=0;$i<$nb_mots;$i++)
  {
  	$poids=1;
  	while ($les_mots[$i]==$les_mots[$i+1])
  	{
    $poids=$poids+1;
    $i=$i+1;
  	}
  	echo "<br>".$les_mots[$i]."\n";
  	echo $poids;
  	//on est sorti de la boucle parce que $les_mots[$i]!=$les_mots[$i+1]
  	//on teste maintenant si $les_mots[$i] est dans la liste des mots vide
  	$sql="SELECT * from MOTS_VIDE";
  	$curseur = mysql_query($sql);
  	$ligne = mysql_fetch_array($curseur);  
  	while($ligne[0]!=$les_mots[$i])
  	{
    $ligne=mysql_fetch_array($curseur);
  	}
  	if ($ligne[0] == $les_mots[$i])
  	{
    echo "mot vide, pas d'insertion";
  	}
  	else //sortie de boucle car $les_mots[$i] n'est pas dans le tableau des mots vide, donc insertion!!!!
  	{
    $req1="INSERT INTO mot (Mot, Poids) VALUES ( '".mysql_real_escape_string($les_mots[$i])."','".mysql_real_escape_string($poids)."')";
    $result1=mysql_query($req1,$CONNEXION);
    if($result1)
    {
    	echo "<br>enregistrement pris en compte";
    }
    else
    {
    	echo "<br>recommencer, erreur dans l' enregistrement";
    }
  	}	
  }

le temsp d’exécution est beaucoup trop long, ce qui me parait normal puisque je peux avoir beaucop beaucoup beaucoup de mot dans un fichier, mais c’est tellement long que je ne vois pas au final ce que ça me donne, même si j’ai mis un temps rallongé de 1h :


set_time_limit(3600);

je ne sais pas trop si mes requêtes sont bonnes, ni comment gérer tout ça, enfin, là, je ne sais pas trop quoi faire!!!!!!

Tu n’aurais pas un boucle infinie par hasard? ($i et $ligne n’ont pas l’air de bouger dans ta boucle ??)
(rappel: initialisation, contrôle des invariants de boucle, de la condition de terminaison, toussa quoi :smiley: )
sinon, effectivement, si la liste des mots vide est vraiement trop longue à traiter, alors (1)recherche plutôt ton mot en SQL, ou alors, (2)tu insère tous les mots, même les mots vide, et à la fin tu supprime les mots vides insérés par un “delete from mot where mot in select * from mot_vide”

j’ai trouvé une autre solution finalement, qui marche


for ($i=0;$i<$nb_mots;$i++)
  {
  	$poids=1;
  	while ($les_mots[$i]==$les_mots[$i+1])
  	{
    $poids=$poids+1;
    $i=$i+1;
  	}
  	echo "<br>".$les_mots[$i]."\n";
  	echo $poids;
  	//on est sorti de la boucle parce que $les_mots[$i]!=$les_mots[$i+1]
  	[COLOR=red]$sql="SELECT mot_vide FROM mots_vide WHERE mot_vide='$les_mots[$i]'";
  	$curseur = mysql_query($sql);
  	if($ligne = mysql_fetch_row($curseur))	
  	{
    echo "mot vide, pas d'insertion";
  	}[/COLOR]
  	else //insertion car ce n'est pas un mot vide
  	{
    $req1="INSERT INTO mot (Mot, Poids) VALUES ( '".mysql_real_escape_string($les_mots[$i])."','".mysql_real_escape_string($poids)."')";
    $result1=mysql_query($req1,$CONNEXION);
    if($result1)
    {
    	echo "<br>enregistrement pris en compte";
    }
    else
    {
    	echo "<br>recommencer, erreur dans l' enregistrement";
    }
  	}	
  }

Ca marche, mais bien sur, comme un code doit toujours être optimiser le plus possible, et bien flute, il faut que je me creuse la tête pour faire autrement!!!
Je m’explique,j’ai comme code pour le moment :


	function split_words($string)
  {
  	$retour = array(); //array() : crée un tableau
	
  	$delimiteurs = " .!?,:;«»'`(){}[]%\/–©";
  	$tok = strtok($string, " ");
  	while (strlen(join(" ", $retour)) != strlen($string)) //strlen : Retourne la taille de la chaîne string.  
    	//join()", capable de fusionner une chaîne de caractères (vide ici) et un tableau ("contenu").
  	{
    array_push($retour, $tok); //array_push : "Entasse" des éléments dans un tableau.
    $tok = strtok ($delimiteurs); //strtok : Découpe une chaîne de caractères selon les délimiteurs qui lui sont passés en paramètre soit  .!?,:;«»(){}[]%\/–©
  	}
  	return array_non_empty($retour);
  }

//Cett e fonction supprime les entrées vides d'un tableau 
	function array_non_empty($array)
  {
  	$retour = array();
  	foreach ($array as $a)
  	{
    if ((!empty($a)) && (strlen($a) >= 2)) //empty : Détermine si une variable contient une valeur non nulle
                //on garde les mots de 2lettre ou plus
    {
    	array_push($retour, trim($a));//array_push :  Empile un ou plusieurs éléments à la fin d'un tableau
            //trim :  Supprime les espaces (ou d'autres caractères) en début et fin de chaîne
    }
  	}
  	return $retour;
  }
  $contenu1 = strtolower($contenu1);
  $les_mots = split_words($contenu1); //tableau mot par mot
  $nb_mots = count($les_mots);
  $i = 0;
  sort($les_mots); //tableau des mots par ordre alphabétique
  for ($i=0;$i<$nb_mots;$i++)
  {
  	$poids=1;
  	while ($les_mots[$i]==$les_mots[$i+1])
  	{
    $poids=$poids+1;
    $i=$i+1;
  	}
  	echo "<br>".$les_mots[$i]."\n";
  	echo $poids;
  	//on est sorti de la boucle parce que $les_mots[$i]!=$les_mots[$i+1]
  	$sql="SELECT mot_vide FROM mots_vide WHERE mot_vide='$les_mots[$i]'";
  	$curseur = mysql_query($sql);
  	if($ligne = mysql_fetch_row($curseur))	
  	{
    echo "mot vide, pas d'insertion";
  	}
  	else //insertion car ce n'est pas un mot vide
  	{
    $req1="INSERT INTO mot (Mot, Poids) VALUES ( '".mysql_real_escape_string($les_mots[$i])."','".mysql_real_escape_string($poids)."')";
    $result1=mysql_query($req1,$CONNEXION);
    if($result1)
    {
    	echo "<br>enregistrement pris en compte";
    }
    else
    {
    	echo "<br>recommencer, erreur dans l' enregistrement";
    }
  	}	
  }

et il faudrait que je fasse la selection des mots non vide dans ma fonction array_non_empty($array), ceci dit, euh, coment faire sachant que pour le moment, j’ai besoin de $les_mots[$i] pour savoir si c’est un mot vide ou pas !!! enfin je ne sais pas si je me suis bien fait comprendre??? comprenez-vous l’idée??? en faite il faut que mon tableau de mot ne comporte aucun mot qui se trouve dans ma table de mot vide!!!
merci deltree, et sans nom, vous qui prenez le temps de me répondre et de m’aider!!!