 |
|
 |
public bool IsPalindrome(string stringToCheck)
{
char[] rev = stringToCheck.Reverse().ToArray();
return (stringToCheck.Equals(new string(rev), StringComparison.OrdinalIgnoreCase));
}
zamirsblog.blogspot.com
|
|
|
|
 |
|
 |
I thought the "on the basis of words" type was "fall leaves after leaves fall".
|
|
|
|
 |
|
 |
that kind of highlights the whole issue - the solution of palindromes is very much dependant on what you want to accept as a palindrome...
hopefulyy the article solves most kinds of plaindromes, and gives a starting point for all the others...
"When the only tool you have is a hammer, a sore thumb you will have."
|
|
|
|
 |
|
 |
I believe this may accomplish the same result: bool IsPalindrome
(string theString)
{
Collection<char> charsLR = new Collection<char>();
Collection<char> charsRL = new Collection<char>();
for (int index=0; (index < theString.Length); index++) {
if (Char.IsLetter (theString[index])) {
charsLR.Add (theString[index]);
charsRL.Insert (0, theString[index]);
}
}
return charsLR.Equals (charsRL);
}/ravi
|
|
|
|
 |
|
 |
Better to have short-circuit failure -- return false as soon as you can, without processing further characters.
|
|
|
|
 |
|
 |
Wouldn't that require 2 passes?
/ravi
|
|
|
|
 |
|
|
 |
|
 |
Sorry, I guess what I meant was 2 indexed access into the string (one L to R, the other R to L). My method only does a single access into the source string (at the expense of walking the entire string).
(To whoever 1-voted my note):
I'm not suggesting it's optimal; I was only offering an alternative.
/ravi
|
|
|
|
 |
|
 |
Ravi Bhavnani wrote: (one L to R, the other R to L).
They both stop at the center of the string.
With your solution you traverse the entire string, and then the Equal will traverse it at least partway, perhaps the whole way.
With the solution presented (and mine*, and others) we traverse the string at most once (or halfway twice if you like).
In some cases we'll only compare the first and last characters.
* Actually, my Purify method will also the traverse the string as well, whereas the solution presented won't.
|
|
|
|
 |
|
|
 |
|
 |
you would only need to go halfway:
for (int index=0; (index < theString.Length / 2); index++)
"When the only tool you have is a hammer, a sore thumb you will have."
|
|
|
|
 |
|
 |
True, and the compare would check the characters at [index] and the [length-index], with consideration being made for the odd number length case.
/ravi
|
|
|
|
 |
|
 |
I happened to have this sitting in my personal library:
Private Function TestPalindrome(ByVal Text As String, _
ByVal IgnoreCase As Boolean, _
ByVal IgnoreWhitespace As Boolean, _
ByVal IgnorePunctuation As Boolean) As Boolean
If IgnoreCase Then Text = Text.ToLower
If IgnoreWhitespace Then Text = Regex.Replace(Text, "\s", String.Empty)
Text = Regex.Replace(Text, "[^\w\s]", String.Empty)
Dim TextChar() As Char = Text.ToCharArray
For Index As Integer = 0 To TextChar.Length / 2 - 1
If TextChar(Index) <> TextChar(TextChar.Length - Index - 1) Then Return False
Next
Return True
End Function
|
|
|
|
 |
|
 |
Wow, that's a lot of traversals of the string.
1) ToLower
2) Remove whitespace
3) Remove punctuation
4) Convert to array -- which isn't even necessary
5) And finally across the array
You could also use string.Replace rather than Regex.Replace
And I suspect it otherwise works like mine... throws an Exception if the string is null and returns true if it's empty.
|
|
|
|
 |
|
 |
A reason to review my palindrome checking method (looks like I wrote it four years ago).
Mine is simplified by the use of my Purify method which, in this usage, removes any characters that I want to ignore.
public static bool
IsPalindrome
(
string subject
)
{
return ( IsPalindrome ( subject , "ABCDEFGHIJKLMNOPQRSTUVWXYZ" ) ) ;
}
public static bool
IsPalindrome
(
string subject
,
string goods
)
{
bool result = true ;
subject = PIEBALD.Lib.LibStr.Purify ( subject.ToUpper() , goods , null , null , null ) ;
for ( int runner = 0 ; runner < subject.Length/2 && result ; runner++ )
{
result = subject [ runner ] == subject [ subject.Length - 1 - runner ] ;
}
return ( result ) ;
}
Hmmm... I think I can change it to a while loop and use a HashSet to contain the desired characters...
|
|
|
|
 |
|
|
 |
|
 |
Note the cleverly hidden ToUpper.
|
|
|
|
 |
|
 |
oh, I saw that I meant in the case of:
"A man, a plan, a canal - Panamá!"
"When the only tool you have is a hammer, a sore thumb you will have."
|
|
|
|
 |
|
 |
Oh, right, well inspired by your article I spent all day yesterday reworking mine. Thank you very little.
But because some Unicode glyphs require more than one character, a fully-Unicode-compliant palindrome detector may be even more difficult than I thought and I'm trying very hard not to work on it today... maybe all weekend though.
P.S. I just tested what I did yesterday and it properly handles "A man, a plan, a canal - Panamá!" when I specify that the HashSet<char> is to use the InvariantCulture, IgnoreNonSpace, and IgnoreCase.
P.P.S. I just tested my current version with the Hebrew and Greek examples from the Wikipedia page; the Hebrew and Medieval Greek examples returned true, the Modern Greek example (with psi) returned false.
I had forgotten to ignore whitespace -- the Modern Greek returns true.
modified on Friday, August 29, 2008 6:12 PM
|
|
|
|
 |
|
 |
opps sorry, did not mean to cause you so much work!
"When the only tool you have is a hammer, a sore thumb you will have."
|
|
|
|
 |
|
 |
It's alright, if I didn't enjoy programming I'd be doing something else.
Anyway, I spent last evening writing a struct which contains a string to hold either a single char or a surrogate pair, and a comparer to work with them, then reworked my IsPalindrome methods to use the new struct. I have tested it with the examples mentioned and it works, but I still need to test it with surrogate pairs (if I can find some). I'm also doing more reading up on Unicode to see what else I may have missed.
|
|
|
|
 |