J'ai une chaîne en PHP. Je veux échanger un certain caractère avec la valeur d'un autre caractère. Si je le fais à ma manière, A devenant B remplacera A par B mais les valeurs B déjà existantes resteront les mêmes. Lorsque j'essaye de permuter B en A, il y a bien sûr des valeurs qui n'ont pas été échangées à l'origine, car elles étaient déjà là.
J'ai essayé ce code.
$hex = "long_hex_string_not_included_here"; $hex = str_replace($a,$b,$hex); //using this later will produced unwanted extra swaps $hex = str_replace($b,$a,$hex);
Je recherche une fonction pour permuter ces valeurs.
5 Réponses :
Utilisez une valeur Temp (qui n'apparaît pas dans votre chaîne. Cela peut être n'importe quoi):
$temp = "_"; $a = "a"; $b = "b"; $hex = "abcdabcd"; $hex = str_replace($a, $temp, $hex); // "_bcd_bcd" $hex = str_replace($b, $a, $hex); // "_acd_acd" $hex = str_replace($temp, $a, $hex); // "bacdbacd" // Or, alternativly a bit shorter: $temp = "_"; $a = "a"; $b = "b"; $hex = str_replace([$a, $b, $temp], [$temp, $a, $b] $hex);
Mais bien sûr, vous devrez vous assurer que la valeur C n'existe pas déjà dans la chaîne ou vous obtiendrez un autre résultat indésirable
Nous pourrions simplement essayer de remplacer une troisième valeur intermédiaire par B , puis remplacer tous les A par B , puis remplacez le marqueur par A . Mais cela laisse toujours ouverte la possibilité que le caractère marqueur puisse déjà apparaître quelque part dans la chaîne.
Une approche plus sûre consiste à convertir la chaîne d'entrée en un tableau de caractères, puis à parcourir le tableau en vérifiant simplement chaque index pour A ou B , et permutez en conséquence.
$input = "AzzzzB";
echo $input ."\n";
$arr = str_split($input);
for ($i=0; $i < count($arr); $i++) {
if ($arr[$i] == 'A') {
$arr[$i] = 'B';
}
else if ($arr[$i] == 'B') {
$arr[$i] = 'A';
}
}
$output = implode('', $arr);
echo $ouput;
AzzzzB
BzzzzA
Notez également que cette approche est efficace et ne nécessite que de parcourir l'entrée chaîne une fois.
Bien que cela n'ait pas le problème de la valeur intermédiaire existant dans la chaîne, cela ne fonctionnera pas pour les longueurs de caractères> 1. Et je suis curieux de savoir comment cela fonctionne. Mon intermédiaire a un remplacement supplémentaire, mais c'est aussi une manipulation de chaîne. J'aime cette réponse, +1.
Utilisez simplement strtr . C'est ce pour quoi il a été conçu:
bacacb
Résultat:
$string = "abcbca";
echo strtr($string, array('a' => 'b', 'b' => 'a'));
La fonctionnalité clé qui aide ici est que lorsque strtr code> est appelé sous la forme à deux arguments:
Une fois qu'une sous-chaîne a été remplacée, sa nouvelle valeur ne sera plus recherchée.
C'est ce qui empêche le a qui a été remplacé par b d'être à nouveau remplacé par a .
J'ai cloué la question d'entretien, vous avez donné la meilleure réponse +1.
Une autre façon pourrait être de str_split la chaîne et d'utiliser array_map par caractère. Si a , renvoyez b et vice versa. Sinon, renvoie la valeur d'origine.
baab test abba
Résultat
$hex = "abba test baab";
$hex = array_map(function ($x) {
return ($x === 'a') ? 'b' : (($x === 'b') ? 'a' : $x);
}, str_split($hex));
echo implode('', $hex);
Ma solution fonctionne pour une sous-chaîne. Le code n'est pas clair mais je veux vous montrer une façon de penser.
$html = "dasdfdasdff";
$firstLetter = "d";
$secondLetter = "a";
$firstLetterPositions = array();
$secondLetterPositions = array();
$lastPos = 0;
while (($lastPos = strpos($html, $firstLetter, $lastPos))!== false) {
$firstLetterPositions[] = $lastPos;
$lastPos = $lastPos + strlen($firstLetter);
}
$lastPos = 0;
while (($lastPos = strpos($html, $secondLetter, $lastPos))!== false) {
$secondLetterPositions[] = $lastPos;
$lastPos = $lastPos + strlen($secondLetter);
}
for ($i = 0; $i < count($firstLetterPositions); $i++) {
$html = substr_replace($html, $secondLetter, $firstLetterPositions[$i], count($firstLetterPositions[$i]));
}
for ($i = 0; $i < count($secondLetterPositions); $i++) {
$html = substr_replace($html, $firstLetter, $secondLetterPositions[$i], count($secondLetterPositions[$i]));
}
var_dump($html);
Cela n'échoue-t-il pas lorsque vous remplacez une chaîne par une autre valeur de longueur? Par exemple. 'a' avec 'bb'? Cette solution est assez exagérée par rapport aux remplacements de 3 chaînes et n'offre pas beaucoup de valeur.