PDA

View Full Version : problem with deque<string>::iterator



sax94
29th January 2012, 08:32
hey everyone
i'm a student of c++ language. I have to implement an RPN calculator. RPN stands for revers polish notation and it's a more simple way o resolve equations. I was debugging the code when a really strange problem(for me) jumped out. I tried resolving (3+2)*5, this equation in RPN looks like this 3 2 + 5 *, my program does this, finds the "+" and erase it from my deque, the iterator goes back one space so know point to 2, finds the 2, he puts it in a variable called tmp and then erase it, the iterator know points at 3, he does tmp+3 and puts the result where the 3 was, and does the same operation with the 2 remaining number 5 5 *.
but if I pu (3+2)*5+4, everything in my program changes and I can't undestrand why. the problem is that going to resolve the same bit of before 3 2 +, when i erase the + the iterator doesn't point a 2 but at 3. this is my code


if(*it=="*"||*it=="+"||*it=="/"||*it=="-")
{
string sign=*it;
output.erase(it),*it--,str=*it;
strcpy(cstr,str.c_str());
tmp=atoi(cstr);
output.erase(it),*it--;
str=*it;
strcpy(cstr,str.c_str());
output.erase(it),*it--;
if(sign=="+")
tmp=tmp+atoi(cstr);
else if(sign=="-")
tmp=atoi(cstr)-tmp;
else if(sign=="*")
tmp=atoi(cstr)*tmp;
else if (sign=="/")
tmp=atoi(cstr)/tmp;
itoa(tmp,cstr,10);
str=cstr;
*it++;
output.insert(it,str);
it=output.begin();
}
*it++;

can someone help me?
thanks
P.S. sorry for my english

wysota
29th January 2012, 12:15
If you have a stack (aka deque) there is no point in using iterators as you should always be grabbing from the top. When solving 3 2 + 5 * you should be taking '*', then requiring two arguments you should ake 5, then take '+' and since it is an operator, make a recursive call to solve the '+' operation taking 3 and 2 in the process.

Another way is to not put everything on the stack but proceed from the beginning, you have a stream of tokens and you place 3 and 2 and + on the stack, since + is an operator, take it off along with two preceding arguments, calculate the result and push it onto the stack, then continue pushing from the stream until you reach the next operator, etc.

sax94
29th January 2012, 13:36
thank you, probably that's a better way for solving the problem, but didn't answer to my question, I want to understand why my code does this strange thing and solve the problem!
thanks

wysota
29th January 2012, 13:48
That's usually what happens if you're modifying the structure you are currently iterating.

You also have these strange kinds of statements: "*it--". What is it supposed to do?

sax94
29th January 2012, 15:53
*it-- should set the iterator to point the deque section before the one it was pointing, how should I do?
you se if I have this deque 3 2 + 5 * and I erase (with mydeque.erase(it)) the + the it points o 5, but i want it pointing to 2 so i do *it-- and i works with this string, but if I have 3 2 + 5 * 4 + or every other sequence with more than 5 characters then when i erase one element, for example he first + it points al ready o 2 and not 5 has it should be, and so doing *it-- I point to 3 and so the result isn't correct. this is my problem

wysota
29th January 2012, 16:24
*it-- should set the iterator to point the deque section before the one it was pointing
What's the asterisk for then? it-- would do just fine.


you se if I have this deque 3 2 + 5 * and I erase (with mydeque.erase(it)) the + the it points o 5, but i want it pointing to 2 so i do *it-- and i works with this string, but if I have 3 2 + 5 * 4 + or every other sequence with more than 5 characters then when i erase one element, for example he first + it points al ready o 2 and not 5 has it should be, and so doing *it-- I point to 3 and so the result isn't correct. this is my problem

If you delete the item the iterator points to, you get unexpected behaviour. First move the iterator where you want it to be and then remove the item. However doing what you do now -- you are making it much harder than it really is. For instance there is no point in using deque, with your approach a regular vector would do and you could use index-based counting instead of iterators.

sax94
29th January 2012, 17:43
sorry, hate to ask, could you make me a code example because i'm trying to do what you told me but the results are always the same!
thank's

wysota
29th January 2012, 18:17
I'm sorry, we're not allowed to give solutions for student projects. We can only push you in the right direction.

sax94
29th January 2012, 18:22
ok, then i'll repost my code


if(*it=="*"||*it=="+"||*it=="/"||*it=="-")
{
if(*it-->"0"||*it<"9"&&*it-->"0"||*it<"9")
{
*it++,*it++;
string sign=*it;
it--,output.erase(output.begin()+count);
str=*it;
strcpy(cstr,str.c_str());
tmp=atoi(cstr);
it--,output.erase(output.begin()+(count-1)),str=*it;
strcpy(cstr,str.c_str());
output.erase(output.begin()+(count-2));
if(sign=="+")
tmp=tmp+atoi(cstr);
else if(sign=="-")
tmp=atoi(cstr)-tmp;
else if(sign=="*")
tmp=atoi(cstr)*tmp;
else if (sign=="/")
tmp=atoi(cstr)/tmp;
itoa(tmp,cstr,10);
str=cstr;
output.insert(it,str);
it=output.begin();
}

thank's for you help and your patience

sax94
30th January 2012, 12:18
problem solved, thanks!