2
votes

Comparaison de chaînes quel que soit l'ordre PHP

Je veux savoir s'il existe un moyen de comparer au moyen d'une méthode PHP, et vérifier que deux chaînes quel que soit l'ordre sont les mêmes,

par exemple:

$ string1 = "Pedro Perez";
$ string2 = "Perez Pedro";

Ma question est donc de savoir comment puis-je rendre cela VRAI dans une comparaison. De toute évidence, votre commande la rend différente.


Je pose cette question parce que je développe une recherche, et je veux qu'une comparaison de $ string1 et $ string2 soit considérée comme la même valeur, quel que soit le l'ordre qu'ils ont, tant que la chaîne a les mêmes mots


4 commentaires

|| ? Pourquoi vérifier les deux si 1 est vrai et répond à votre condition? o.O


essayez $ string1 == $ string2


vous pouvez vérifier si la chaîne contient plusieurs mots. Ajoutez ensuite à un tableau et vérifiez si le tableau contient les mêmes valeurs


Si vous développez une recherche, vous pouvez la placer dans un index FULLTEXT en utilisant un Recherche en langage naturel et laissez MySQL s'en occuper ...


5 Réponses :


6
votes

Vous le décomposez par un espace et coupez les deux tableaux comme suit et vérifiez son compte

$string1 = "Perez Perez Pedro";
$string2 = "Perez Pedro Perez";
list($s1,$s2) = [explode(" ", $string1), explode(" ", $string2)];
sort($s1);sort($s2);
var_dump($s1 === $s2);

MODIFIER

Pour plus de deux mots ici est l'extrait,

$string1 = "Pedro Perez";
$string2 = "Perez Pedro";
$s1 = array_unique(explode(" ", $string1));
$s2 = array_unique(explode(" ", $string2));
$temp = array_intersect($s1, $s2);
var_dump(count($temp) == count($s1) && count($temp) == count($s2));

Travail démo a >.


5 commentaires

Approche géniale.


Cela donnera des résultats erronés si les tableaux contiennent des éléments deux fois: cas de test


Cela dépend des exigences si cela vous convient. 'Perez Perez Pedro' et 'Perez Pedro Pedro' donneraient true après array_unique , ce qui ne semble pas juste selon la question.


@Namoshek J'ai apporté des modifications. Vérifiez s'il vous plaît


Malheureusement, cela pose toujours un problème avec les entrées numériques en raison de la comparaison de type non sécurisée avec == au lieu de === : scénario de test



0
votes

Vous pouvez essayer de faire ceci.

  1. Convertissez la chaîne en tableau en la fractionnant sur des espaces.
  2. Trier le tableau.
  3. Reconvertissez le tableau en chaîne.
  4. Comparez les deux.

De manière simple, c'est parti ...

<?php
  $string1 = "Pedro Perez";
  $string2 = "Perez Pedro";
  $string1 = explode(" ", $string1);
  $string2 = explode(" ", $string2);
  // Update: You don't save the output of sort, as it's by reference.
  sort($string1);
  sort($string2);
  $string1 = implode(" ", $string1);
  $string2 = implode(" ", $string2);
  var_dump($string1 === $string2);
?>


1 commentaires

Je ne pense pas que la partie imploser soit nécessaire. Une comparaison stricte des tableaux avec === donnera true si les tableaux contiennent les mêmes éléments dans le même ordre. Et la vérification est même sécurisée et n'essaie pas de convertir les types.



2
votes

Encore une autre approche

$string1 = "Pedro Perez";
$string2 = "Perez Pedro";
$s1 = explode(" ", $string1);
$s2 = explode(" ", $string2);
$comp = empty( array_diff($s1, $s2) ) ? true : false;


1 commentaires

Cela donnera également des résultats erronés si les tableaux contiennent des éléments deux fois: cas de test



3
votes

La partie triviale est de diviser les chaînes en mots et de comparer les tableaux par taille. Si la taille n'est pas la même, les chaînes ne peuvent pas être les mêmes:

$words1 = array_count_values($words1);
$words2 = array_count_values($words2);

// Comparison 1
$intersect = array_intersect_assoc($words1, $words2);
return count($intersect) === count($words1) && count($words1) === count($words2);

// Comparison 2
$diff = array_diff_assoc($words1, $words2);
return empty($diff);

Avec cela établi, nous avons pas mal de solutions possibles pour la comparaison réelle de deux tableaux de mots, qui devraient être dans un ordre différent.

Déjà suggéré Nr. 1

Trier et comparer (simplifié sans implode):

sort($words1);
sort($words2);

return $words1 === $words2;

Ceci est sûr à faire et ne changera pas l'entrée car les chaînes sont copiées lorsqu'elles sont passées à une fonction et nous avons même copié la chaîne en plusieurs parties lors de l'utilisation de explode.

Construction de dictionnaires

Comptage des occurrences de chaque mot et la prise en compte du nombre de mots évite les problèmes que d'autres solutions rencontrent avec les mots qui apparaissent deux fois dans les chaînes d'entrée. Cette solution permet également de sélectionner différentes comparaisons des dictionnaires:

function str_equals_ignore_word_order(string $str1, string $str2): bool
{
    $words1 = explode(' ', $str1);
    $words2 = explode(' ', $str2);

    if (count($words1) !== count($words2)) {
        return false;
    }

    // Here comes one of the following or already suggested solutions.
}

Remarquable

Si l'on s'attend à ce que l'entrée contienne des fautes d'orthographe comme deux espaces juste après l'autre '' , vous devez utiliser array_filter ($ words1) sur les deux tableaux de mots pour vous assurer qu'aucun mot NULL ne correspond.


0 commentaires

0
votes

Une petite fonction pour le plaisir, qui ne trie pas si nécessaire.

  • Comparez le nombre de mots de la chaîne divisée,
  • trier les tableaux de mots,
  • comparer des tableaux de mots.
// Split the sentences, compare word count, sort words, compare sorted words
function compare_words($a, $b) { 
  return count($a = explode(' ', $a)) == count($b = explode(' ', $b)) 
    && sort($a) 
    && sort($b) 
    && $a === $b;
};


0 commentaires