PHP初学者回文脚本

时间:2011-07-17 06:17:44

标签: php algorithm palindrome

我正在努力(为了好玩)编写一个可以识别回文的脚本。到目前为止,我成功地使用了“皮划艇”,“赛车”,“安娜”,“一个男人计划运河巴拿马”:然而后一个短语的变体如“amanaplana canalpan ama”给了我一些问题。

作为旁注:我确实理解使用PCRE会让事情变得更容易,但我不能流利,我的主要目标之一是了解背后的算法检查回文。

 <?php
$word = "amanaplana canalpan ama";

$space = " ";
$word_smallcase = strtolower($word);        

$word_array = str_split($word_smallcase);   

if(in_array($space, $word_array)){      

    for($m = 0; $m<count($word_array); $m = $m + 1){
        if($word_array[$m] == $space)
            unset($word_array[$m]);
    }
}
$count = 0;
$scan_count = -1;
for($i = 0; $i < (count($word_array)/2); $i = $i + 1){

    for($j = count($word_array); $j > (count($word_array)/2); $j = $j - 1){

        if($word_array[$i]==$word_array[$j]){
            $count = $count + 1;
            break;
            }
        }
    $scan_count = $scan_count + 1;

        }
if ($count == $scan_count){
    echo $word." is a palindrome";
}
else{

    echo $word ." is NOT a palindrome";
}


?>

我很感激有关的回复:

  • 识别我遇到的错误。
  • 关于的建议 我怎么可能改进代码(如果我能做的话,我会很高兴 事情的工作,而不是诉诸$ count或$ scan_count似乎, 我的眼睛,相对业余的。)

提前致谢。

5 个答案:

答案 0 :(得分:3)

目前,您正在逐字逐句地进行测试,这肯定会导致在回文中字词不均匀的情况下出现错误。

在PHP中查看字符串是否是palandromic的简单方法:

$test = str_replace( array(',', '.', ' '
                     //, and any other punctuation you aren't using
                     ), '', $input );

$test = strtolower( $test );
echo $input . ' is ' . 
             ( ( strrev( $test ) == $test )? "": "not " )
             ' palandromic.';

关于你的代码:迭代数组并同时删除东西是一个麻烦的邀请。你最好只使用str_replace。如果那不是一个选项,我会使用:

// this takes more space, but it is easier to understand.
$tmp = array();
for($m = 0; $m<count($word_array); $m++){ // ++ is the same as $m = $m + 1
    if($word_array[$m] != $space)
        $tmp[] = $word_array[$m];
}
$word_array = $tmp;

如果没有strrev(反转字符串):

$l = count( $word_array ) / 2; // cache this, no sense in recounting
$is_palindromic = TRUE;
for( $i = 0; $i < $l; $i++ )
{
    if( $word_array[ $i ] != $word_array[ ( -1 - $i ) ] )
    {
        $is_palindromic = FALSE;
        break;
    }
}

echo $input . ' is ' . 
         ( $is_palindromic )? "": "not " )
         ' palandromic.';

答案 1 :(得分:2)

这里有一些事情......

首先,我不确定你是否知道unset数组实际上并没有删除索引:

$array = array(0, 1, 2, 3);
unset($array[2]);
var_dump($array);
/* array(3) {
  [0]=>
  int(0)
  [1]=>
  int(1)
  [3]=>
  int(3)
} */

因此,当您遍历数组中的元素时,您将会有一些未定义的偏移量。要逐个使用,您应该使用foreach循环控件。

另一个问题在于嵌套for循环:

for($i = 0; $i < (count($word_array)/2); $i = $i + 1){

    for($j = count($word_array); $j > (count($word_array)/2); $j = $j - 1){

鉴于“amanaplanacanalpanama”,看看你在做什么:

逐步比较(顺便说一下,你在$ j的初始值设定项上是1; $word_array[count($word_array)]指向巴拿马的'm'而不是'a'。):< / p>

a eq to a?              j is 22          i is 0
                scan_count: -1   count: 1
m eq to a?              j is 22          i is 1
m eq to m?              j is 21          i is 1
                scan_count: 0    count: 2
a eq to a?              j is 22          i is 2
                scan_count: 1    count: 3

a eq to a很好,匹配...... m在下一次迭代中找到,但是当你到达下一个'a'时,你会发现巴拿马末尾的原始'a'。 ..

作为旁注,由于你每次都是从最后开始的,所以考虑到一个足够大的字符串,它会非常低效O(n^2) ...

强制性解决方案:

$word = "amanaplana canalpan ama";

$j = strlen ($word)-1;
$pal = true;

for ($i = 0; $i < strlen($word)/2; ++$i, --$j) {

    // skip spaces
    while ($word[$i] === " ") {$i++;}
    while ($word[$j] === " ") {$j--;}

    echo "$word[$i] eq $word[$j]?\n";
    if ($word[$i] !== $word[$j])    {
        $pal = false;
        break;
        }
}

if ($pal) print "yes"; else print "no";

答案 2 :(得分:1)

伪代码:

string phrase = "my phrase here"

int i = 0
int j = phrase.length - 1

while i < j:
  if phrase[i] is not alphanumeric:
    i++;
    continue;
  if phrase[j] is not alphanumeric:
    j--;
    continue;
  if phrase[i] != phrase[j]
    return false;
  i++;
  j--;

return true

答案 3 :(得分:0)

认为可以删除所有空格并完全忽略单词。如果字符串长度为奇数,则分成两部分(或左右),反转任意一半,然后查看它们是否匹配。

$word = "amanaplana canalpan ama";

$sanitizedWord = preg_replace("'\s+'", '', strtolower($word));
$halfway = strlen($sanitizedWord)/2;
$roundedDownMidPoint = floor($halfway);

$firstHalf = substr($sanitizedWord, 0, $roundedDownMidPoint);
$secondHalf = substr($sanitizedWord, is_float($halfway) ? $roundedDownMidPoint+1 : $halfway);

if ($firstHalf === strrev($secondHalf)) {
    echo $sanitizedWord." is a palindrome";
}

使用“Kayak”,“Racecar”,“Anna”,“A a a plan a canal a Panama”和“amanaplana canalpan ama”进行测试,这些都被正确识别为回文。

答案 4 :(得分:0)

<?php
$a="amanaplana canalpan ama";
echo "String entered: " . $a;
$b= preg_replace('/\s+/', '', $a);
$org= strtolower($b);
$chk= strrev($org);
echo "<br/>";
if ($org==$chk)
{ echo "Palindrome"; }
else
{ echo "Not Palindrome"; }
?>