没有strrev的反向string

前段时间,在面试时,我得到了一个任务,在使用strrev 情况下,在PHP中反转string。

我的第一个解决scheme是这样的:

 $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" 

然后他们问我是否可以做到这一点,没有加倍的内存使用(不使用$tempvariables或任何variables复制反向string),我失败了。 这一直困扰我,从那以后我试图解决这个问题,但我经常失败。

我最近的尝试是这样的:

 $s = 'abcdefg'; for ($i = 0, $length = mb_strlen($s); $i < $length; $i++) { $s = $s{$i * 2} . $s; } var_dump($s); // outputs string(14) "gfedcbaabcdefg" 

这不是在循环之后切断“abcdefg”的解决scheme,因为那样我仍然会使用的内存量增加一倍。 我需要删除每个迭代循环中的最后一个字符。

我试图像这样使用mb_substr

 $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); 

但它只给我Uninitialized string offset错误。

这是我卡住(再次)。 我尝试了谷歌search,但所有我find的解决scheme直接echo显字符或使用临时variables。

我也发现问题PHPstring反转,而不使用额外的内存,但没有答案,符合我的需要。

这是一个有趣的。 这是我刚刚提出的事情:

 $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()可以用来在一个操作中分配一个variables列表。 所以我正在做的只是交换字符(从第一个和最后一个开始,然后是第二个和第二个等等,直到到达string的中间)

输出是mlkjihgfedcba 。 没有使用任何其他variables比$s和计数器,所以我希望这符合您的标准。

你可以使用这个事实,在PHP中,一个string可以被认为是一个字符数组 。

然后,基本上你想要做的就是将string中间左侧的每个字符$ireplace为中间右侧的字符$j ,并使用相同的距离。

例如,在一个由7个字符组成的string中,中间字符在位置3上。位置0(距离3)上的字符需要与位置6(3 + 3)上的字符交换,位置1上的字符(距离2 )需要与位置5(3 + 2)等字符交换

这个algorithm可以实现如下:

 $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))); 

你可以使用XOR交换技巧。

 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"); 

尝试这个:

 $s = 'abcdefg'; for ($i = strlen($s)-1; $i>=0; $i--) { $s .= $s[$i]; $s[$i] = NULL; } var_dump(trim($s)); 

PHPstring有点不稳定 ,但由于写入时复制,在原地修改它们是非常困难的,而不需要复制 。 上述的一些解决scheme的工作,但只是因为他们是独立的; 有些已经失败了,因为它们没有通过引用参数定义一个函数。 为了让代码在一个更大的程序中实际运行,你需要注意赋值,函数参数和范围。

例:

 $string1 = 'abc'; $string2 = $string1; $string1[0] = 'b'; print("$string1, $string2"); > "abc, bbc" 

我猜想,如果在初始化variables和修改它之间,只能使用引用赋值( &= )和引用参数( function rev(&$string) )( 或者最初将string赋值给一个对象属性,它的任何其他variables ),您可能能够更改string的原始值,而不做任何副本。 但是,这有点荒谬,我想这位提出这个问题的访问者并不知道关于复制的问题。

顺便说一句,这与其他语言的不变性不太一样,因为它也适用于数组:

 $a = [0, 1, 2]; $b = $a; $b[0] = 1; print(implode($a).implode($b)); > "012112" 

总而言之,除非您专门使用&=操作符,否则所有types(PHP5 以外的对象除外 )都将使用copy-on-write进行分配。 这个赋值不会复制它们,但是与大多数其他语言(C,Java,Python …)不同,它会改变原始值(数组)或者根本不允许写入访问(string),PHP会默默地创build在进行任何更改之前复制。

当然,如果你切换到一个更传统的指针语言,也切换到字节数组而不是string,你可以使用异或来交换每个字符对:

 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] 

这里是这个PHP7版本:

 echo "\u{202E}abcdefg"; // outs: gfedcba 

基本上@EricBouwers答案,但你可以删除第二个占位符variables$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; } 

testing输出:

 echo strrev2("Hi there!"); // "!ereht iH" echo PHP_EOL; echo strrev2("Hello World!"); // "!dlroW olleH" 

这将通过列表中途停止,它交换最左边和最右边,并工作的方式向内,停在中间。 如果是奇数,则数字不会与自身交换,如果是偶数,则交换中间两位并停止。 使用的唯一额外内存是$len ,方便性和$tmp交换。

如果你想要一个函数不返回string的新副本,而只是编辑旧的函数,你可以使用下面的代码:

 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" 

使用&$str传递一个直接指针的string进行编辑。

对于像@treegardens这样简单的实现,你可以重写为:

 $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; 

它有类似的逻辑,但我相当简化了for循环。

这是我的代码来解决你的问题

  <?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); ?> 

太简单了

 //Reverse a String $string = 'Basant Kumar'; $length = strlen($string); for($i=$length-1;$i >=0;$i--){ echo $string[$i]; } 

您也可以使用recursion来反转string。 像这样的东西,例如:

 function reverse($s) { if(strlen($s) === 1) return $s; return substr($s, strlen($s)-1) . reverse(substr($s , 0, strlen($s)-1)); } 

你在这里所做的实际上是返回string的最后一个字符,然后再次调用与包含没有最后一个字符的初始string的子string相同的函数。 当你的string只是一个字符的时候,你就结束了recursion。

您可以使用此代码来反转string,而不使用php中的保留函数。

码:

 <?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"); ?> 

输出:

 tneduts a ma I 

在上面的代码中,我们已经传递了string的值作为参数。我们已经使用for循环执行了string反转。

你可以使用substr与负面开始。

理论与解释

你可以从for循环开始,计数器从1到string的长度,并在counter * -1它将计数器转换为负值 )和长度为1迭代内调用substr

所以第一次计数器是1 ,乘以-1会变成-1

因此substr('abcdefg', -1, 1); 会让你g
和下一次迭代substr('abcdefg', -2, 1); 会让你f
substr('abcdefg', -3, 1); 会让你e
等等 …

 $str = 'abcdefghijklmnopqrstuvwxyz'; for($i=1; $i <= strlen($str); $i++) { echo substr($str, $i*-1, 1); } 

在行动: https : //eval.in/583208

 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.'; } } 
 //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; 

下面的解决scheme非常简单,但它的工作:

 $string = 'Andreas'; $reversedString = ''; for($i = mb_strlen($string) - 1; $i >= 0; $i--){ $reversedString .= $string[$i]; } 

var_dump($reversedString)然后结果: string(7) "saerdnA"

  <?php $value = 'abcdefg'; $length_value = strlen($value); for($i = $length_value-1; $i >=0 ;$i--){ echo $value[$i]; } ?> 

你可以试试这个..

 $string = "NASEEM"; $total_word = strlen($string); for($i=0; $i<=$total_word; $i++) { echo substr($string,$total_word-$i,1); } 

尝试这个

 $warn = 'this is a test'; $i=0; while(@$warn[$i]){ $i++;} while($i>0) { echo $warn[$i-1]; $i--; }