没有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"
然后他们问我是否可以做到这一点,没有加倍的内存使用(不使用$temp
variables或任何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中间左侧的每个字符$i
replace为中间右侧的字符$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--; }