March 11, 2008 – 2:56 am
You can reverse the list and then match it to the original or try to solve it how humans actually check if a string is a palindrome. That is by simultaneously scanning the string from left to right and right to left char by char checking if they match. The only thing new is the true and false keyword.
Also make sure your bounds on the list are set correctly and this problem can be broken up into three base cases.
1) low < high
This means we are still scanning the string. We match the corresponding char and check if they are equal. If they are not, its not a palindrome and return false. If they are recursive call the function moving the bounds by 1.
1) low = high
Well if low = high that means that they are pointing at the same char and therefore can return true since the recursive function would had caught a case where the scanning did not match chars. This string is also of odd length.
3) low > high
This happens when the bounds cross each from the recursive calls. Only happens with strings of equal length. Case 1 would had caught the string by now if it wasn’t a palindrome, thus it is safe to return true.
let is_palindrome (listy : List<char>) =
let rec is_palindrome_rec (list : List<char>) low high =
if (low = high) then
true
elif (low < high) then
if (List.nth list low) = (List.nth list high) then
is_palindrome_rec list (low + 1) (high - 1)
else
false
else true
in is_palindrome_rec listy 0 (List.length listy - 1)
Notice the elif keyword which is equal to else if. Some optimization can lead to
let is_palindrome (listy : List<char>) =
let rec is_palindrome_rec (list : List<char>) low high =
if (low < high) then
if (List.nth list low) = (List.nth list high) then
is_palindrome_rec list (low + 1) (high - 1)
else
false
else true
in is_palindrome_rec listy 0 (List.length listy - 1)
Since case 2 and 3 return the same result. Of course reversing the list and comparing it to the original is a lot smarter, efficient and faster way of doing this but at least this way you may struggle a bit and learn a bit more.
Some test cases.
if ( is_palindrome ['a';'b';'c';'d';'e'] )
then ( Printf.printf "Failed!" )
else ( Printf.printf "Success!" );;
if ( is_palindrome ['a';'b';'c';'b';'a'] )
then ( Printf.printf "Success!" )
else ( Printf.printf "Failed!" );;
Posted in 99 problems, F# | No Comments »