views:

463

answers:

4

Hello,

I am writing a simple program, which is trying to find next palindrome number after given number.

As for now, I am stuck at this point:

string::iterator iter; // iterators for the string
string::iterator riter; 


//testcases is a vector<string> with strings representing numbers.
for (unsigned int i = 0; i < testcases.size() ; ++i) {
    iter = testcases[i].begin();
    riter = testcases[i].end();

    while ( !isPalin(testcases[i]) ) { //isPalin(string) is a function
                                       //which is checking if given string
                                       //is a palindrome

        //if n-th digit from the end is different from the
        //n-th digit, then I want to replace latter one, so they will 
        //be the same.
        if ( *iter != *riter ) {
            testcases[i].replace(riter, riter, *iter);
        }

        ++iter; // advancing forward iterator;
        --riter; // advancing backward iterator;
    }
    cout << testcases[i] << " -> ok\n";
}

When I am compiling this one using Microsoft Visual Studio 2008, I am getting this error:

Compiling...
main.cpp
.\main.cpp(53) : error C2664: 'std::basic_string<_Elem,_Traits,_Ax> &std::basic_string<_Elem,_Traits,_Ax>::replace(unsigned int,unsigned int,const std::basic_string<_Elem,_Traits,_Ax> &)' : cannot convert parameter 1 from 'std::_String_iterator<_Elem,_Traits,_Alloc>' to 'unsigned int'
        with
        [
            _Elem=char,
            _Traits=std::char_traits,
            _Ax=std::allocator
        ]
        and
        [
            _Elem=char,
            _Traits=std::char_traits,
            _Alloc=std::allocator
        ]
        No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called

Am I doing something stupid or am I missing something? I would be grateful for any help / suggestion.

+2  A: 

About the code you have:

Why don't you just assign the values at the end of the two iterators?

if ( *iter != *riter ) {
   *riter = *iter;
}

As Oli pointed out, there are other problems in the code, the first of which is the fact that you are setting riter to be string.end(), witch is a non-dereference-able iterator. end() iterators are always one past the end, and thus the use above will try to write beyond the assigned memory.

Maybe you should try using .rbegin() instead. It will provide a reverse iterator pointing to the last element that moves towards the beginning of the string as you increment it.

On the algorithm:

If your intention is finding the next number that is a palindrome, I am not sure that the algorithm you have implemented is correct. As an example, if the input number is 123456 the algorithm will detect that it is not a palindrome and will convert to 12345_1_ which is smaller than the original number.

David Rodríguez - dribeas
@dribeas - thank You for suggestions and analysis of my code. You are right in every aspect - I will improve code concerning what You have posted and post the improved - (and hopefully working) version later. I just need to start checking this string not from the beginning - but from the middle, but without Your sugesstions - I wouldn't have noticed that.
zeroDivisible
+1  A: 

You are trying to use an overload which replaces one character in the string. If you see the member functions of string, the particular overload of replace you are trying to use requires the number of characters you are replacing. Hence you should change your code to:

testcases[i].replace(riter, riter, 1, *iter);
Naveen
+2  A: 

In addition to dribeas' answer I suggest you to initialize riter to ".end() - 1" in order to avoid overindexing the string.

Olli
A: 

The problem you seem to be having is that the first parameter of replace(...) needs to be an unsigned int and your giving a string iterator. Have you tried to add a * before that string iterator to get the contents of the iterator?

Partial