Palindrone tester

Pages: 1234
Jul 12, 2012 at 9:09pm
How is my palindrone tester deal? I know it's not perfect, I wrote in about 5 minutes.

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
bool is_palindrone(unsigned long int n)
{
    //Int to string
    std::string strProd = "";
    std::stringstream ss;
    ss << n;
    strProd = ss.str();

    //Creates reversed copy.
    std::string reversed;
    int sz = strProd.size();
    for(int i = sz; i > -1; i--)
    {
        reversed[sz - i] = strProd[i];
    }

    //Checks for palindrone
    if(strProd == reversed)
    {
        return true;
    }
    else
    {
        return false;
    }
}


EDIT:
Doesn't work. I should test things first.
Last edited on Jul 12, 2012 at 9:13pm
Jul 12, 2012 at 9:22pm
Haha. I like the edit. :-)

Also, I think the term is palindrome.

Could you maybe loop backwards through each character of the string and assign that to the new string then compare?
Last edited on Jul 12, 2012 at 9:24pm
Jul 12, 2012 at 9:23pm
Ah that would explain those damn red lines. Thanks for the catch though!
Anyway, got the reversing to work, but the comparison isn't working. Here's the updated function.

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
bool is_palindrone(unsigned long int n)
{
    //Int to string
    std::string strProd = "";
    std::stringstream ss;
    ss << n;
    strProd = ss.str();

    //Creates reversed copy.
    std::string reversed;
    int sz = strProd.size();
    for(int i = sz; i > -1; i--)
    {
        reversed.push_back(strProd[i]);
        std::cout << reversed << "\n";
    }

    //Checks for palindrone
    if(strProd.compare(reversed) == 0)
    {
        return true;
    }
    else
    {
        return false;
    }
}


Running it prints out each step of the reverse, and the end product is the reversed copy of the original, so some reason the check at the end is failing.

EDIT:
When trying to actually output it like I have now, in the original way, it caused a crash. Probably because on iteration one, the string is uninitialized. I'm assuming, if someone wants to shed some light there that would be cool
Last edited on Jul 12, 2012 at 9:27pm
Jul 12, 2012 at 9:39pm
Next attempt. Not sure why it keeps returning false, probably some small thing I'm missing like always.

This is replacing the current check for palindrome section:

1
2
3
4
5
6
7
8
9
10
11
//Checks for palindrome
    bool palindrome = true;
    for(unsigned int i = 0; i < strProd.size(); i++)
    {
        if(strProd[i] != reversed[i])
        {
            palindrome = false;
            break;
        }
    }
    return palindrome;
Jul 12, 2012 at 9:39pm
I think i might need to be one less in the first iteration maybe?

Here's my crack anyway (ignore the dodgy indentation - VS2010):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
bool IsPalindrome(unsigned long int n)
{
   //Int to string
   string my_str,
          rev_str;

   stringstream ss;

   ss << n;
   my_str = ss.str();

   int lc = my_str.length();
   while(lc--)
   {
      rev_str.append(my_str.substr(lc, 1));
   }

   cout << "my_str: " << my_str << "\trev: " << rev_str << endl;
   
   if(my_str == rev_str)
      return true;
   else
      return false;
}


Edit: Fixed indentation.
Last edited on Jul 12, 2012 at 9:44pm
Jul 12, 2012 at 9:42pm
Hmm, we seem to accomplish the same thing in different ways. I dont know if you saw, but I added some output to check to make sure it's getting reversed, and it is.

Does your check work?
Jul 12, 2012 at 9:44pm
Yeah, seems to. Returns 1 when I enter a palindrome, 0 if not.

Not sure why your check isn't working if both string are the same when printed. No odd spaces or anything?

Edit: Getting some problems with bigger numbers, I think. I shall investigate further.
Last edited on Jul 12, 2012 at 9:47pm
Jul 12, 2012 at 9:50pm
Found the error. I thought maybe it was adding something hidden in there (ie a space or something) and found it. Here's an output:


Enter a number: 76767
        1
 7      2
 76     3
 767    4
 7676   5
 76767  6


Anyway here's the line of code I added.

std::cout << reversed << "\t" << reversed.length() << "\n";

In the loop that reverses the string. So I think you were right.
Last edited on Jul 12, 2012 at 9:55pm
Jul 12, 2012 at 9:58pm
Now do it without reversing the string.
Jul 12, 2012 at 10:15pm
@helios,

I had that thought when I started it, but had never done and only had a little bit of time left in the day. After I get this done, im gonna go back and do it that way. I feel like its gonna be ugly though
Jul 12, 2012 at 10:32pm
How about this? I haven't fully tested it yet, though. Ignore stupid indentation.

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
bool NoReverse(string str)
{
	int len = str.length();

	if(len%2 == 0)
	{
		// Even length
		cout << "Even length\n";
		for(int i=0; i < (len/2)+1; i++)
		{	
			if(str.substr(i,1) != str.substr(len-1-i,1))
				return false;
		}
	}
	else
	{
		// Odd length
		cout << "Odd length\n";
		for(int i=0; i != (len/2)+1; i++)
		{
			if(str.substr(i,1) != str.substr(len-1-i,1))
				return false;
		}
	}
	
	return true;
}


Edit: Passed a string to omit the stringstream stuff. Obviously now it'll work on any characters, not just digits. For only digits, some sort of isdigit check could be included before checking the string.
Last edited on Jul 12, 2012 at 10:44pm
Jul 12, 2012 at 10:43pm
iHutch105: That's terrible.
* What do you use the parity check for?
* Don't use std::string::substr().
Jul 12, 2012 at 10:51pm
Figured it out. I'm pretty sure I was grabbing the \0 character at the end of the primary string, and sticking it in the first spot of the reversed string.

1
2
3
4
5
6
7
8
//Creates reversed copy.
    std::string reversed;
    int sz = strProd.size();
    for(int i = sz-1; i > -1; i--)
    {
        reversed.push_back(strProd[i]);
        std::cout << reversed << "\n";
    }


Changed it to start at sz-1

ASFAIK, this works. It's worked for the few test cases I've given it. Let me know what you think/where it can be improved.
Last edited on Jul 12, 2012 at 10:52pm
Jul 12, 2012 at 10:55pm
Whoops, didn't realise how similar my loops got there as I worked on them separately.

Why not use substr, though?

This better?

1
2
3
4
5
6
7
8
9
10
11
12
bool NoReverse(string str)
{
	int len = str.length();

	for(int i=0; i < (len/2)+1; i++)
	{	
		if(str[i] != str[len-1-i])
			return false;
	}
	
	return true;
}
Last edited on Jul 12, 2012 at 10:57pm
Jul 12, 2012 at 11:00pm
I am curious what's wrong with substr() here. I personally think it's less readable, but is there an actual issue with it?
Jul 12, 2012 at 11:07pm
I guess it is a little less readable, yeah.

It's a work habit I've picked up - we have our own string class with a substr function that does some sort of error checking.
Jul 12, 2012 at 11:11pm
I think helios don't like to use substr here because it's unnecessary slow.
Jul 12, 2012 at 11:16pm
substr() allocates memory. Using it to make string comparisons just reeks of laziness.
Jul 12, 2012 at 11:18pm
Oh, ok, I see.

Is the later post preferred?
Jul 12, 2012 at 11:26pm
Cool, finished Euler #4. Was pretty easy. Though, what I have right now seems pretty inefficient. It only takes me 2.8 seconds, but I know there is a lot of unneccesary calculations in there. Here's what I got:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
unsigned long int product = 0, answer = 0;
    int operand1 = 0, operand2 = 0;
    for(unsigned int i = 999; i > 0; i--)
    {
        for(unsigned int j = i; j > 0; j--)
        {
            product = i * j;
            if(is_palindrome(product) && product > answer)
            {
                answer = product;
                operand1 = i;
                operand2 = j;
            }
        }
    }

    std::cout << "Answer is: " << answer << "\tProduct of " << operand1 << " and " << operand2;


Any ideas on how to cut down on the calculations that aren't needed? Originally, I had it stop at the first palindrome it found, but that wasn't right. And I see why now.
Last edited on Jul 12, 2012 at 11:27pm
Pages: 1234