Created
October 26, 2010 14:43
-
-
Save weberste/647025 to your computer and use it in GitHub Desktop.
Find the longest substring (within a given string) that is the same in reverse.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
object ReverseSubstring { | |
/** | |
* Find the longest substring (within a given string) that is the same in reverse. | |
* Example: "I like bananas but not cucumbers." should return "anana". | |
*/ | |
def main(args: Array[String]) { | |
val biggestSubstring = findBiggestReverseSubstring(args(0)) | |
println("biggest substring is '%s'".format(biggestSubstring)) | |
} | |
def findBiggestReverseSubstring(text: String): String = { | |
val arrayText = text.toArray | |
val substrings = (0 until text.length).map(findBiggestReverseSubstringStartingFrom(_, text)) | |
substrings.max(new Ordering[String] { | |
def compare(x: String, y: String): Int = { | |
x.length - y.length | |
} | |
}) | |
} | |
/** | |
* Returns the biggest reverse substring by expanding around 'startingPos'. | |
*/ | |
def findBiggestReverseSubstringStartingFrom(startingPos: Int, text: Seq[Char]): String = { | |
require(startingPos >= 0 && startingPos < text.length, "precondition not met: startingPos is out of bounds") | |
def expandReverseSubstring(leftPos: Int, rightPos: Int, text: Seq[Char]): String = { | |
require(isReverseSubstring(text.view(leftPos, rightPos + 1)), "precondition not met: current selection is not a reverse substring") | |
if (leftPos > 0 && rightPos < text.length - 1 && isReverseSubstring(text.view(leftPos - 1, rightPos + 2))) | |
expandReverseSubstring(leftPos - 1, rightPos + 1, text) | |
else | |
text.slice(leftPos, rightPos + 1).toString | |
} | |
val oddLengthMaxString = expandReverseSubstring(startingPos, startingPos, text) | |
val evenLengthMaxString = expandReverseSubstring(startingPos, startingPos - 1, text) | |
if (oddLengthMaxString.length > evenLengthMaxString.length) | |
oddLengthMaxString | |
else | |
evenLengthMaxString | |
} | |
def isReverseSubstring(text: Seq[Char]): Boolean = { | |
val splitIdx = text.length / 2 | |
text.take(splitIdx) == text.reverse.take(splitIdx) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Linear time solution: http://www.akalin.cx/2007/11/28/finding-the-longest-palindromic-substring-in-linear-time/