Palindrome

Pages: 12
@PlanetNumbed


By the way your code is bad and invalid.
And why is that vlad. Can you give a better shorter code than what I just posted huh ?
@vlad from moscow - By the way your code is bad and invalid.


Invalid ? It's Perfect, try it in some c++ compiler !
Give me a better and shorter code than this :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include <conio.h>
#include <string>
using namespace std; 

void main()
{	
        string str,wrd="";	
	cout << "\nEnter a literal : ";
	cin >> str;
	for(int i=str.length()-1;i>=0;i--)
		wrd=wrd+str[i];
	if(wrd==str)
		cout << "\n" << str << " is a palindrome" << endl;
	else
		cout << "\n" << str << " is not a palindrome" << endl;
_getch();
}
Please read the thread. I already showed the simple way to determine that a string is a palindrome. I can repeat

1
2
3
4
if ( str == std::string( str.rbegin(), str.rend() ) )
{
   std::cout << "String \"" << str << "\" is a palindrome" << std::endl;
}


Your code is invalid because you are using an object of type int in the loop while std::string::size_type has an unsigned type. So it can occur that after assigning the value returned by size() to an object of type int it will became negative and the loop will not executed.
Last edited on
I tried my code in Microsoft Visual C++ 2010 Express and it's working with no problems.
I explained you already why your code is bad. For example the string can be read from a file and has size that exceeds the maximum value of type int. In such case after the assignment

int i=str.length()-

i can be negative.

and the loop will not be executed though the string is valid.

By the way this code

string str,wrd="";

is also ignorant because by default after definition of an object of type std::string it will be empty. So there is no any need to write

string wrd = "";

because it is equivalent to

string wrd;


Last edited on
@vlad from moscow


Can you explain if ( str == std::string( str.rbegin(), str.rend() ) )

I am new to C++ so please explain me the functions you have used in this.
std::string( str.rbegin(), str.rend() ) is a constructor of class std::string that takes as arguments iterators (pointers) of the last and the first elements of the original object 'str' and builds a new object that is the reverse copy of the original object.

You can write a simple test program

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <string>

int main()
{
   std::string s( "Hello World" );

   std::cout << s << std::endl;
   
   std::string t( s.rbegin(), s.rend() );

   std::cout << t << std::endl;

   return 0;
}
Last edited on
Thanks for helping but how can int i=str.length() be negative ?
It is very simple.

Consider a simple example

unsigned char c1 = '\xff';
signed char c2 = c1;

What value will c2 have?

Or you can consider another example

1
2
3
4
5
6
7
int x = 0;
unsigned int i = 0;

while ( 0 <= ( x = i ) ) i++;

std::cout << "i = " << i << std::endl;
std::cout << "x = " << x << std::endl;



I got the following result:

i = 2147483648
x = -2147483648
Last edited on
Because an int is signed and string::size_type is not.

My computer certainly can't make a string of 0x80000000 characters, but that is length of the string that you would have undefined behaivor
What are signed and unsigned ?

And I have tried out my program several times with different kinds of inputs but I am not facing any sort of error. Can you please show me an example of this negative problem you are talking about on the basis ( like some specific input which triggers such a problem ) of my code :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <string>
using namespace std; 

void main()
{	
        string str,wrd;	
	cout << "\nEnter a literal : ";
	cin >> str;
	for(int i=str.length()-1;i>=0;i--)
		wrd=wrd+str[i];
	if(wrd==str)
		cout << "\n" << str << " is a palindrome" << endl;
	else
		cout << "\n" << str << " is not a palindrome" << endl;
system("PAUSE");
}
Last edited on
> Can you please show me an example of this negative problem you are talking about

Can't show you an example; but we can certainly talk about a hypothetical situation - on your implementation, an (impossible) string containing 2.2 billion or more characters.

In theory there is no difference between theory and practice. In practice there is. - Yogi Berra(?)


Check this out if it interests you:
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
#include <iostream>
#include <algorithm>
#include <locale>

bool is_palindrome( const std::string& str, const std::locale& loc = std::locale() )
{
    // we want to ignore punctuation, whitespace, capitalization and non-printable chars
    std::string s ;
    for( char c : str ) if( std::isalnum(c,loc) ) s += std::tolower(c,loc) ;

    // we need to check only if the first half of the string is the reverse of the second half
    // std::equal - http://en.cppreference.com/w/cpp/algorithm/equal
    //              note: there is a palindrome example at the end of the page
    // rbegin() yields an iterator that iterates backward from the last character
    return !s.empty() && std::equal( s.begin(), s.begin()+s.size()/2, s.rbegin() ) ;
}

int main()
{
    const std::string phrases[] =
    {
        "Palindromes often consist of a phrase or sentence",
        "Punctuation, capitalization, and spacing are usually ignored",
        "A man, a plan, a canal - Panama!",
        "Do geese see God?"
    };

    for( const std::string& str : phrases ) if( is_palindrome(str) )
         std::cout << str << '\n' ;
}

http://liveworkspace.org/code/1J7O4z$0
You take positive values that are in range for the type int. Type std::string::size_type for example on 64-bit platforms can corresponds to long long. So the result of the assignment

int i = str.length();

can be invalid.
I already explained you the difference between the signed and unsigned numbers. Are you unable to understand this from the first time?
What are signed and unsigned ?


A number that can be negative is signed. The "signed bit" is the most significant bit. ints are too big to show an example, but we can use char:

First, binary numbers can be written with an 0b prefix:
1
2
3
4
5
char x = 0b1111; // x = 15

// char and unsigned char both use 8 bits
char sch = 0b10000000;  // signed bit, sch = -127
unsigned char uch = 0b10000000; // not observing signed bit, uch = 128 


You can run this program:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <bitset>
#include <iomanip>
using namespace std;

int main (int argc, char **argv)
{
  char sch;
  unsigned char uch;
  for (int i = 0; i < 256; i++)
  {
    sch = i;
    uch = i;
    
    cout <<   "Signed  : " << bitset<8>(sch) << setw(5) << (int)sch << " ";
    cout << "\tUnSigned: " << bitset<8>(uch) << setw(5) << (int)uch << '\n';
  }
  return 0;
}


Note that even though the bits are the same, the interpretation is different.

You can store the string's length as a char, in which the problem is apparent:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <string>
using namespace std;

int main (int argc, char **argv)
{
  string str(128, '.');  // creates a string with 128 periods
  char signedlength = str.length();
  std::cout << (int)signedlength << '\n';

  unsigned char unsignedLength = str.length();
  std::cout << (int)unsignedLength << '\n';
  
  return 0;
}


Then of course, the reason not to use chars for this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <string>
using namespace std;

int main (int argc, char **argv)
{
  string str(256, '.');
  char signedlength = str.length();
  std::cout << (int)signedlength << '\n';

  unsigned char unsignedLength = str.length();
  std::cout << (int)unsignedLength << '\n';
  
  return 0;
}


Which is why, instead of this:
1
2
3
4
5
6
7
int x = str.length();

// or even this
unsigned int x = str.length();

// use this
std::string::size_type x = str.length();  // never a problem 
Last edited on
Got it thanks .. But why do people use int main() and then do return 0 because that's worthles when you can just do a simple void main()
The return value reports to the environment that run the program how the program was finished. This value can be used for example in batch packet to select a next action depending on the return code.
You may omit the statement return 0; if you want. In this case the compiler ittself will insert required code that will be equivalent to return 0.

So the shortest program in C++ is

int main() {}
Last edited on
#include<iostream>
#include<stdio.h> //for using the gets() function
using namespace std ;

int main()
{
char string[100] ; //character array to store a string
cout<<"\nEnter a string:-\n" ;
gets(string) ; //accepted the string from user
int l, i, j, flag = 1 ; //declared a flag
/*The following loop finds the length of the string */
for( l = 0 ; string[l] != '\0' ; l++ ) ;
/*The following loop matches each character from the beginning and
end consecutively, i.e., the 1st character and the last character
would be matched, then if it matches, the 2nd the the second last
character would be matched and so on. In case a character doesn't
match, the value of the flag is changed and the loop is terminated
using break*/
for( i = 0 , j = l - 1 ; i < l / 2 ; i++, --j )
{
if(string[i] != string[j])
{
flag = 0 ;
break ;
}
}
if(flag == 1)
cout<<"\nString is a palndrome" ;
else
cout<<"\nString is not a palindrome" ;
return 0 ;
}
Topic archived. No new replies allowed.
Pages: 12