PHP - Efficiency while searching for palindrome
I was challenged by a friend to code some PHP to find the longest palindrome in provided text, my solution is below, how could I make it more efficient?
$string = file_get_contents("http://challenge.greplin.com/static/gettysburg.txt");
echo $string;
function isPalendrone($string) {
if ($string == strrev($string))
return true;
else
return false;
}
$longest = "";
for($i = 0; $i < strlen($string)-1; $i++) {
$afterCurrent = substr($string, $i);
for($j = 0; $j < strlen($afterCurrent)-1; $j++) {
$section = substr($afterCurrent, 0, $j);
if(isPalendrone($section)) {
if(strlen($longest)<strlen($section)) {
$longest = $section;
}
}
}
}
echo "<br /><br/>The longest was: ".$longest."<br /> which is ".strlen($longest)." chars lo开发者_如何学编程ng";
This reverses the entire string and just does substr()
matches against each:
$rev = strrev($txt);
$len = strlen($txt);
$longest_len = 0;
$longest_str = null;
for ($i = 0; $i < $len; ++$i)
{
for ($j = $len - $i; $j > $longest_len; --$j)
{
if (substr($txt, $i, $j) == substr($rev, $len-$i-$j, $j))
{
$longest_len = $j;
$longest_str = substr($txt, $i, $j);
break;
}
}
}
I didn't try to optimize the implementation. e.g., It might be a little faster to skip the substr
and do a char-by-char approach, because you could break out faster. In that case, you wouldn't really even need to reverse the string.
To get the longest palindrome - you have to start with longest string (not with shortest like you do now), check it and break on first match.
Also you'd better just keep 2 pointers ($i
and $j
) and not perform substr
twice. It is enough to have i and j and substr
once, right before you perform if(isPalendrone())
condition.
My implementation (~20% faster than yours):
<?php
$string = 'FourscoreandsevenyearsagoourfaathersbroughtforthonthiscontainentanewnationconceivedinzLibertyanddedicatedtothepropositionthatallmenarecreatedequalNowweareengagedinagreahtcivilwartestingwhetherthatnaptionoranynartionsoconceivedandsodedicatedcanlongendureWeareqmetonagreatbattlefiemldoftzhatwarWehavecometodedicpateaportionofthatfieldasafinalrestingplaceforthosewhoheregavetheirlivesthatthatnationmightliveItisaltogetherfangandproperthatweshoulddothisButinalargersensewecannotdedicatewecannotconsecratewecannothallowthisgroundThebravelmenlivinganddeadwhostruggledherehaveconsecrateditfaraboveourpoorponwertoaddordetractTgheworldadswfilllittlenotlenorlongrememberwhatwesayherebutitcanneverforgetwhattheydidhereItisforusthelivingrathertobededicatedheretotheulnfinishedworkwhichtheywhofoughtherehavethusfarsonoblyadvancedItisratherforustobeherededicatedtothegreattdafskremainingbeforeusthatfromthesehonoreddeadwetakeincreaseddevotiontothatcauseforwhichtheygavethelastpfullmeasureofdevotionthatweherehighlyresolvethatthesedeadshallnothavediedinvainthatthisnationunsderGodshallhaveanewbirthoffreedomandthatgovernmentofthepeoplebythepeopleforthepeopleshallnotperishfromtheearth';
function isPalendrone($string) {
return $string == strrev($string);
}
$longest = '';
$length = strlen($string);
for ($i = 0; $i < $length - 1; $i++) {
for ($j = $length - $i; $j > 1; $j--) {
if (isPalendrone(substr($string, $i, $j))) {
$new = substr($string, $i, $j);
if (strlen($new) > strlen($longest)) $longest = $new;
break;
}
}
}
echo "<br /><br/>The longest was: ".$longest."<br /> which is ".strlen($longest)." chars long";
精彩评论