Il y a quelque temps, lors d'un entretien d'embauche, j'ai eu pour tâche d'inverser une chaîne dans PHP sans à l'aide de strrev
.
Ma première solution ressemblait à ceci:
$s = 'abcdefg';
$temp = '';
for ($i = 0, $length = mb_strlen($s); $i < $length; $i++) {
$temp .= $s{$length - $i - 1};
}
var_dump($temp);
// outputs string(7) "gfedcba"
puis ils m'ont demandé si je pouvais le faire sans doubler l'utilisation de la mémoire (en n'utilisant pas la variable $temp
ni aucune variable pour copier la chaîne inversée) et j'ai échoué . fois mais j'ai constamment échoué.
Mon dernier essai ressemble à ceci:
$s = 'abcdefg';
for ($i = 0, $length = mb_strlen($s); $i < $length; $i++) {
$s = $s{$i * 2} . $s;
}
var_dump($s);
// outputs string(14) "gfedcbaabcdefg"
Ce n'est pas une solution pour couper "abcdefg" après la boucle car je doublerais encore la quantité de mémoire utilisée. Je dois supprimer le dernier caractère de chaque itération de la boucle.
J'ai essayé d'utiliser mb_substr
comme ceci:
$s = 'abcdefg';
for ($i = 0, $length = mb_strlen($s); $i < $length; $i++) {
$s = $s{$i * 2} . mb_substr($s, $length - $i - 1, 1);
}
var_dump($s);
mais cela ne me donne que des erreurs Uninitialized string offset
.
C'est là que je suis coincé (encore). J'ai essayé de googler, mais toutes les solutions que j'ai trouvées ont soit echo
les caractères directement, soit une variable temporaire.
J'ai également trouvé la question PHP inversion de chaîne sans utiliser de mémoire supplémentaire mais il n'y a pas de réponse à la mesure de mes besoins.
C'est intéressant. Voici quelque chose que je viens de proposer:
$s = 'abcdefghijklm';
for($i=strlen($s)-1, $j=0; $j<$i; $i--, $j++) {
list($s[$j], $s[$i]) = array($s[$i], $s[$j]);
}
echo $s;
list()
peut être utilisé pour assigner une liste de variables en une seule opération. Donc, ce que je fais, c'est simplement échanger des caractères (en commençant par le premier et le dernier, puis le deuxième, le premier et l'avant-dernier et ainsi de suite, jusqu'à ce qu'il atteigne le milieu de la chaîne)
La sortie est mlkjihgfedcba
..__ N'utilisant aucune autre variable que $s
et les compteurs, j'espère que cela correspond à vos critères.
Vous pouvez utiliser le fait que, dans PHP, une chaîne peut être considérée comme un tableau de caractères .
Dans ce cas, vous souhaitez fondamentalement remplacer chaque caractère $i
situé à gauche du milieu de la chaîne par le caractère $j
situé à droite au centre, à la même distance.
Par exemple, dans une chaîne de sept caractères, le caractère du milieu est en position 3. Le caractère en position 0 (distance 3) doit être échangé avec le caractère en position 6 (3 + 3), le caractère en position 1 (distance 2). ) doit être échangé avec le caractère en position 5 (3 + 2), etc.
Cet algorithme peut être implémenté comme suit:
$s = 'abcdefg';
$length = strlen($s);
for ($i = 0, $j = $length-1; $i < ($length / 2); $i++, $j--) {
$t = $s[$i];
$s[$i] = $s[$j];
$s[$j] = $t;
}
var_dump($s);
$string = 'abc';
$reverted = implode(array_reverse(str_split($string)));
Essaye ça:
$s = 'abcdefg';
for ($i = strlen($s)-1; $i>=0; $i--) {
$s .= $s[$i];
$s[$i] = NULL;
}
var_dump(trim($s));
Vous pouvez utiliser l'astuce XOR swap.
function rev($str) {
$len = strlen($str);
for($i = 0; $i < floor($len / 2); ++$i) {
$str[$i] = $str[$i] ^ $str[$len - $i - 1];
$str[$len - $i - 1] = $str[$i] ^ $str[$len - $i - 1];
$str[$i] = $str[$i] ^ $str[$len - $i - 1];
}
return $str;
}
print rev("example");
Voici la version PHP7 de ceci:
echo "\u{202E}abcdefg"; // outs: gfedcba
Les chaînes PHP sont un peu mutables , mais, en raison de la copie sur écriture , il est très difficile de les modifier sur place sans qu'une copie ne soit créée. Certaines des solutions ci-dessus fonctionnent, mais uniquement parce qu'elles sont autonomes; certains échouent déjà car ils définissent une fonction sans argument Passe-à-Référence. Pour que le code fonctionne réellement sur place dans un programme plus volumineux, vous devez être particulièrement attentif aux affectations, aux arguments des fonctions et aux étendues.
Exemple:
$string1 = 'abc';
$string2 = $string1;
$string1[0] = 'b';
print("$string1, $string2");
> "abc, bbc"
Je suppose que si, entre l’initialisation de la variable et sa modification, vous n’utilisiez que des assignations de référence (&=
) et des arguments de référence (function rev(&$string)
) (ou affectez la chaîne à une propriété d’objet initialement, puis ne l’assignez jamais variable), vous pouvez pouvoir modifier la valeur d'origine de la chaîne sans effectuer de copie. C'est un peu ridicule, cependant, et je suppose que l'intervieweur qui a posé cette question ne connaissait pas la copie sur écriture.
Ce n'est pas tout à fait la même chose que l'immuabilité dans d'autres langues, d'ailleurs, car cela s'applique aussi aux tableaux:
$a = [0, 1, 2];
$b = $a;
$b[0] = 1;
print(implode($a).implode($b));
> "012112"
Pour résumer, tous les types (sauf pour les objets à partir de PHP5) sont affectés à la copie sur écriture sauf si vous utilisez spécifiquement l'opérateur &=
. L'affectation ne les copie pas, mais contrairement à la plupart des autres langages (C, Java, Python ...) qui changent la valeur d'origine (tableaux) ou n'autorisent pas l'accès en écriture (chaînes), PHP créera une copie en mode silencieux avant d’apporter des modifications.
Bien sûr, si vous passez à une langue avec des pointeurs plus classiques et passez également à des tableaux d'octets au lieu de chaînes, vous pouvez utiliser XOR pour échanger chaque paire de caractères à la place:
for i = 0 ... string.length / 2:
string[i] ^= string[string.length-1-i]
string[string.length-1-i] ^= string[i]
string[i] ^= string[string.length-1-i]
@EricBouwers répond, mais vous pouvez supprimer la 2ème variable de substitution $j
function strrev2($str)
{
$len = strlen($str);
for($i=0;$i<$len/2;$i++)
{
$tmp = $str[$i];
$str[$i] = $str[$len-$i-1];
$str[$len-$i-1] = $tmp;
}
return $str;
}
Testez pour la sortie:
echo strrev2("Hi there!"); // "!ereht iH"
echo PHP_EOL;
echo strrev2("Hello World!"); // "!dlroW olleH"
Cela passera par la liste et s'arrêtera à mi-chemin, il échangera le plus à gauche et le plus à droite, et ira de l'avant vers l'intérieur, et s'arrêtera au milieu. Si le nombre est impair, le chiffre pivot n'est jamais échangé avec lui-même, et s'il est pair, il échange les deux médianes et s'arrête. La seule mémoire supplémentaire utilisée est $len
pour plus de commodité et $tmp
pour la permutation.
Si vous souhaitez une fonction qui ne renvoie pas une nouvelle copie de la chaîne, mais modifie simplement l'ancienne, vous pouvez utiliser les éléments suivants:
function strrev3(&$str)
{
$len = strlen($str);
for($i=0;$i<$len/2;$i++)
{
$tmp = $str[$i];
$str[$i] = $str[$len-$i-1];
$str[$len-$i-1] = $tmp;
}
}
$x = "Test String";
echo $x; // "Test String"
strrev3($x);
echo PHP_EOL;
echo $x; // "gnirtS tseT"
L'utilisation de &$str
passe un pointeur direct sur la chaîne pour la modifier à la place.
Et pour une implémentation plus simple comme @treegardens, vous pouvez réécrire en tant que:
$s = 'abcdefghijklm';
$len = strlen($s);
for($i=0; $i < $len/2; $i++) {
list($s[$i], $s[$len-$i-1]) = array($s[$len-$i-1], $s[$i]);
}
echo $s;
Il a la même logique, mais j’ai un peu simplifié la boucle for.
C'est trop simple
//Reverse a String
$string = 'Basant Kumar';
$length = strlen($string);
for($i=$length-1;$i >=0;$i--){
echo $string[$i];
}
Vous pouvez également utiliser une récursion pour inverser la chaîne. Quelque chose comme ça par exemple:
function reverse($s) {
if(strlen($s) === 1) return $s;
return substr($s, strlen($s)-1) . reverse(substr($s , 0, strlen($s)-1));
}
Ce que vous faites ici renvoie en fait le dernier caractère de la chaîne, puis vous appelez à nouveau la même fonction avec la sous-chaîne contenant la chaîne initiale sans le dernier caractère. Lorsque vous atteignez le point où votre chaîne ne compte qu'un caractère, vous mettez fin à la récursivité.
Voici mon code pour résoudre votre problème
<?php
$s = 'abcdefg';
for ($i = 0, $length = mb_strlen($s); $i < $length; $i++) {
$s = $s{$i}.mb_substr($s,0,$i).mb_substr($s,$i+1);
}
var_dump($s);
?>
Vous pouvez utiliser ce code pour inverser une chaîne sans utiliser la fonction reserved de php.
Code:
<?php
function str_rev($y)// function for reversing a string by passing parameters
{
for ($x = strlen($y)-1; $x>=0; $x--) {
$y .= $y[$x];
$y[$x] = NULL;
}
echo $y;
}
str_rev("I am a student");
?>
Sortie:
tneduts a ma I
Dans le code ci-dessus, nous avons transmis la valeur de la chaîne en tant que paramètre. Nous avons effectué l'inversion de chaîne à l'aide de la boucle for.
vous pouvez utiliser substr
avec un début négatif.
vous pouvez commencer par la boucle for avec un compteur compris entre 1 et la longueur d'une chaîne, puis appelez substr
itération interne avec counter * -1
(qui convertira le compteur en valeur négative) et en longueur de 1
.
Donc, pour la première fois, le compteur serait 1
et en le multipliant par -1
, il deviendra -1
Donc substr('abcdefg', -1, 1);
vous donnera g
et la prochaine itération substr('abcdefg', -2, 1);
vous donnera f
et substr('abcdefg', -3, 1);
vous obtiendrez e
etc ...
$str = 'abcdefghijklmnopqrstuvwxyz';
for($i=1; $i <= strlen($str); $i++) {
echo substr($str, $i*-1, 1);
}
En action: https://eval.in/583208
vous pouvez essayer ça ..
$string = "NASEEM";
$total_Word = strlen($string);
for($i=0; $i<=$total_Word; $i++)
{
echo substr($string,$total_Word-$i,1);
}
j'ai utilisé certaines fonctions intégrées mais sans fonction str_rev.
<?php
$text = "red";
$arr = str_split($text);
$rev_text = array_reverse($arr);
echo join(" ",$rev_text);
?>
<?php
$value = 'abcdefg';
$length_value = strlen($value);
for($i = $length_value-1; $i >=0 ;$i--){
echo $value[$i];
}
?>
public function checkString($str){
if(!empty($str)){
$i = 0;
$str_reverse = '';
while(isset($str[$i])){
$strArr[] = $str[$i];
$i++;
}
for($j = count($strArr); $j>= 0; $j--){
if(isset($strArr[$j])){
$str_reverse .= $strArr[$j];
}
}
if($str == $str_reverse){
echo 'It is a correct string';
}else{
echo 'Invalid string';
}
}
else{
echo 'string not found.';
}
}
Essaye ça
<?php
$str="abcde";
for($i=strlen($str)-1;$i>=0;$i--){
echo $str[$i];
}
?>
sortie
edcba
La solution suivante est très simple, mais elle fait le travail:
$string = 'Andreas';
$reversedString = '';
for($i = mb_strlen($string) - 1; $i >= 0; $i--){
$reversedString .= $string[$i];
}
var_dump($reversedString)
puis résultats: string(7) "saerdnA"
//Reverse String Word by Word
$str = "Reverse string Word by Word";
$i = 0;
while ($d = $str[$i]) {
if($d == " ") {
$out = " ".$temp.$out;
$temp = "";
}
else
$temp .= $d;
$i++;
}
echo $temp.$out;
Ceci est ma solution pour résoudre ce problème.
$in = 'This is a test text';
$out = '';
// find string length
$len = strlen($in);
// loop through it and print it reverse
for ( $i = $len - 1; $i >=0;$i-- )
{
$out = $out.$in[$i];
}
echo $out;