Reputation: 1
I'm am currently trying to write a palindrome that ignores punctuations and case sensitivity, 1 using arrays, the 2nd using pointers. My problem is that I'm unable to figure out how. The code seems to work fine other than that. I've also written a lower case to upper case function, but I don't think it works anyhow.
This is my first code using arrays.
int is_palindrome1(const char phrase[], int length)
{
int first = phrase[0];
int last = phrase[length - 1];
for (length = 0; phrase[length] != '\0'; length++)
{
while (last > first)
{
if ((phrase[first]) != (phrase[last]))
{
return 0;
}
last--;
first++;
}
break;
}
return 1;
}
This is my 2nd palindrome code using pointers.
int is_palindrome2(const char *phrase, int length)
{
int i;
length = strlen(phrase);
for (i = 0; i < length / 2; i++)
{
if (*(phrase + i) != *(phrase + length - i - 1))
{
return 0;
}
}
return 1;
}
Here is my lower case to upper case function.
char lower_to_upper(char lower, char upper)
{
if (lower >= 'a' && lower <= 'z')
{
upper = ('A' + lower - 'a');
return upper;
}
else
{
upper = lower;
return upper;
}
}
Upvotes: 0
Views: 10011
Reputation: 81986
So. Let's do this in steps.
This will look very similar to your code. Except that some syntax problems that you have are fixed. Note that s
and e
point to the first and last character of the string.
bool is_palindrome(const char *phrase, unsigned length) {
const char *s = phrase + 0;
const char *e = phrase + length - 1;
while (s < e) {
if (*s != *e)
return false;
s += 1;
e -= 1;
}
return true;
}
The simplest way to do this is to convert all valid characters to uppercase. It looks like you had this idea as well with your talking about a lower_to_upper()
function.
The only problem is, your function has a really odd signature (why is upper
an argument?). So, an easy fix to that, is to use the builtin function toupper()
.
bool is_palindrome(const char *phrase, unsigned length) {
const char *s = phrase + 0;
const char *e = phrase + length - 1;
while (s < e) {
if (toupper(*s) != toupper(*e))
return false;
s += 1;
e -= 1;
}
return true;
}
Now. The last piece is that you want to ignore spaces and punctuation. Rather than wording it that way, it might be better to talk about the characters that we do want to compare. I think that you are looking to only compare alphanumeric characters. These are a-z, A-Z, and 0-9. To test if a character is one of these, we could build a custom function, or we could use the builtin isalnum()
to do that:
bool is_palindrome(const char *phrase, unsigned length) {
const char *s = phrase + 0;
const char *e = phrase + length - 1;
while (s < e) {
if (!isalnum(*s)) {
s++;
} else if (!isalnum(*e)) {
e--;
} else if (toupper(*s) == toupper(*e)) {
s++;
e--;
} else {
return false;
}
}
return true;
}
Note that on each pass of the loop, we move either s
, e
, or both one step. This ensures that we will eventually complete the loop. Our condition of s < e
also ensure that once we reach the "middle" of the string, that we finish. I put middle in quotes, because for the string "ab a"
, the middle is the second character.
English has a fairly straightforward encoding in most (all?) systems. But other languages are not always that straightforward. In a comment, chux had a recommendation about this:
A locale than may have a many-to-1 mapping of lower to upper or visa-versa, using round-trip if
(tolower(toupper(*s)) != tolower(toupper(*e)))
handles that.
I'm personally not as concerned, because I feel that around the same point that we worry about this, we should also worry about how the text is encoded. Is it UTF-8? Is it something else? This is probably beyond your instructors expectations.
Upvotes: 6