palandrome test using pointers

Pages: 12
i have an assignment for class where i have to use pointers to check if an input is a palindrome. i cant use [] or indexes in my bool function

below is what i have so far but the issue is no matter what i input it says its a palindrome, i did i debug and its not going to the bool function but i dont know why

andy help would be great

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include <iostream>
#include <cstring>
using namespace std;

bool isAPalindrome(char* palindrome);


int main()
{
    char palindrome[30];
    bool palindrome_check;

    cout << "Please enter an word or phrase.\n";
    cin.getline(palindrome, 30);

    palindrome_check = isAPalindrome(palindrome);

    if (palindrome_check = true)
    {
        cout << "Input is a palindrome\n";
    }
    else
    {
        cout << "Inputis not a palindrome\n;";
    }
	system("pause");
	return 0;
}


bool isAPalindrome(char* palindrome)
{
    char* front; 
    char* rear;  

	front = palindrome;// starts at the left side of the c string
	rear = (palindrome + strlen(palindrome)) - 1;//starts at the right side of the c-string. adds the c string plus the incriment value of s
	while (front <= rear)
	{
		if (front = rear)
		{
			front++;
			rear--;
		}
		else
		{
			return false;
		}
	}
    return true;
}
Last edited on
I did not look through all your code but I took into account that this statement

if (palindrome_check = true)

is invalid. You are using the assignment operator instead of the comparision operator, that is there should be

if (palindrome_check == true)

It would be even better if you would write simply

if ( palindrome_check )


EDIT: also in the function that checks whether a word is a palindrome you should write

if ( *front == *rear )

instead of

if (front = rear)
Last edited on
 
if (palindrome_check = true)

this is not a wrong statement but it behaves different to your intention. What this basically does is:

1
2
palindrome_check = true; //Assigns the value 'true' to the variable, overriding the previous value
if(palindrome_check) //Checks if palindrome_check is logically true, which it is because you assigned true it at the previous line 


You should rather do the following:

 
if(palindrome_check == true) //Checks whether palindrome_check equals true 


There is also a mistake in your isPalindrome function:

1
2
3
4
5
6
if( front = rear )

//This basically equals to:

front = rear; //assigns the address of the pointer rear to the pointer front
if( front == true) //Checks if front is logically true (any value greater than zero is logically true) since front is a valid pointer it is greater than zero (not a NULL pointer) and therefore logically true. 


You should use the following:

 
if ( (*front) == (*rear) )


Here you are dereferencing both pointers and checking if the chars they are pointing to are equal
Thank you vlad from moscow and Machtl the code is actually working now

another question i have is: if i input madam im adam it says that it is not a palindrome when it should say its a palindrome, what would i have it add to fix this?

Its the spaces:

madam i

mada m
Last edited on
would i put in a for statement that doesnt read spaces?
You need to modify the way you increment front so that you skip spaces. That is, replace the current "next char" with a "next non-space char".

Similarly for the decrement of rear.

Andy
what if i was to delete all the white spaces between the words and then run it through the palindrome test.
i tried to do cin.get and isalpha but those didnt work.
and ideas?
1
2
3
4
5
6
7
for (int i = 0; i < strlen(palindrome); i++)
	{
		if( palindrome[i] == ' ')
		{
			(palindrome[i]) = '';
		}
	}


i tried this but it says ;
IntelliSense: quoted string should contain at least one character
You can use standard algorithm std::remove that to remove all spaces. For example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
#include <algorithm>
#include <cstring>
 
int main()
{
    char s[] = "This is a test";
    
    std::cout << s << std::endl;
    
    *std::remove( s, s + std::strlen( s ), ' ' ) = '\0';
    
    std::cout << s << std::endl;
}


Or you should write your own algorithm to check whether a string is palindrome by skipping spaces.
well i was trying to think of way to get it to skip over the spaces but i couldnt think of anything to do that, any hints on which part of my code id have to modify to make it skip over the spaces?
1
2
3
4
5
6
7
while ((front) <= rear)
	{
		if ((*front) == (*rear) || (isspace(*front)) || (isspace(*rear)))
		{
			front++;
			rear--;
		}


this code works for one word palindromes and madam im adam but it wont work fro things like a but tuba a santa at nasa and so on
Last edited on
Replacing

front++;

with

1
2
3
do {
    front++;
} while(' ' == *front);


was what I had in mind. And similarly for rear.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
bool isAPalindrome(char* palindrome)
{
	char* front = palindrome;// starts at the left side of the c string
	char* rear = (palindrome + strlen(palindrome)) - 1;//starts at the right side of the c-string. adds the c string plus the incriment value of s
	while (front <= rear)
	{
		if (*front == *rear)
		{
			do {
			    front++;
			} while(' ' == *front);

			do {
			    rear--;
			} while(' ' == *rear);
		}
		else
		{
			return false;
		}
	}
	return true;
}
Last edited on
@andywestken

Your function is wrong. For example consider string "AA "; where the last symbol is blank. Your function will return false though this string is a palindrome.
For general purpose palindromes:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
    template <typename BidirIt>
    bool palindrome(BidirIt first, BidirIt last)
    {
        --last;
        for (;first < last; ++first, --last)
        {
            if (*first != *last)
                return false;
        }
        return true;
    }

int main (int argc, const char * argv[])
{
    std::string d("uppu");
    std::cout << std::palindrome(d.begin(), d.end());
    return 0;
}
@Bourgond Aries


Your function is also wrong because for empty sequences operation --last has undefined behavior.:)
@vlad from moscow

You are right. However, personally I like to implement checks like first != last before actually using the function instead of putting that inside the function. The reason is overhead: if I know the size of the container > 0, then I do not want to check anything.

1
2
3
4
5
6
7
int main()
{
    // ... some containers declared here, unsure if size > 0
    if (!container.empty())
        palindrome(container.begin(), container.end();
    return 0;
}


Also lol, std::palindrome(... xD
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

	while (front <= rear)
	{
		if ((*front) == (*rear) || (isspace(*front)) || (isspace(*rear)))
		{
			do 
			{
			    front++;
			} while(' ' == *front);

			do
			{
			    rear--;
			} while(' ' == *rear);
		}
		else
		{
			return false;
		}
	}
	return true;
}


this one seems to work, accounts for blanks and says "AA " is a palindrome

Thanks you to everyone who is helping out
Last edited on
My code :P

#include<iostream>
#include<string>
#include<conio.h>
#include<algorithm>
#include<cstdlib>

using namespace std;

bool palindrome(char* ptr1,char* ptr2,int len)

{
bool found = true;
for(int i=0;i<len;i++)
{
if(*(ptr1 + i) == *(ptr2 + (len - 1) - i))
{

found = true;

}

else
{
found = false;
break;
}
}

if(found==false)
return(false);
else
return(true);


}




int main()
{
char myStr[100];
int n;
cout<<"enter the length of the string \n";
cin>>n;
cout<<"enter the string \n";
for(int i=0;i<n;i++)
{
cin>>myStr[i];
}


bool found;

found=palindrome(myStr,myStr,n);
cout<<"palindrome : "<<found;

getch();
}


Careful!

If you use this line

if ((*front) == (*rear) || (isspace(*front)) || (isspace(*rear)))

it also thinks that "baaa aaa " is a palandrome, as you're saying that it's a match if either front or back point to a space.

You can handle the leading and trailing spaces by skipping over them before you begin the loop, along the lines of

1
2
3
4
5
6
7
	while(' ' == *front) {
		++front;
	}

	while(' ' == *rear) {
		--rear;
	}


The problem with the "rear" loop is that it cannot handle strings which just contain spaces. The "front" loop with stop at null terminator at end of string, but there's no "null start" to help in the "rear" case.

On top of that, you really want the function to return false for a blank string. If both front and rear move to the other end of a blank string, then the while loop will not run, and the function will return true.

So you need to do something a little bit more involved.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
bool isAPalindrome(char* palindrome)
{
	// if palindrome is NULL, terminate immediately. Dereferencing
	// a null pointer will blow up the program.
	if(NULL == palindrome)
		return false;

	// find the first non-whitespace char (now we know we have some chars)
	char* front = palindrome;
	while(isspace(*front))
	{
		++front;
	}

	// find out how much longer the string is, from the first non-
	// non-whitespace char. If the answer's zero, then we were passed
	// a string containing only whitespace
	size_t len = strlen(front);
	if(0 == len)
		return false;

	// find the last non-whitespace char
	char* rear = front + len - 1;
	while(isspace(*rear))
	{
		--rear;
	}

	while (front <= rear)
	{
#if 0 // enable for debugging
		cerr << *front << " - " << *rear << endl;
#endif

		if ((*front) != (*rear))
			return false;

		do
		{
			++front;
		} while(isspace(*front));

		do
		{
			--rear;
		} while(isspace(*rear));
	}

	return true;
}


Andy


Last edited on
Pages: 12