473,748 Members | 2,617 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

A question about recursion and stacks of objects.

I have a class that looks something like this (Don't try to compile it,
I haven't tested this)

class KVP
{
string key;
string value;
list<KVP> sublist;
};

class MyClass
{
private:
list<KVP> list;
public:
void parseInput(void );
};
My input looks something like.

a=b (Where a is the key and b is the value.)
c=e
d=e
b=c
f=g
h=j
k=l

So the number of tabs tells me how deeply nested I am.
I entend to implement this using a stack of KVPs.

void MyClass::parseI nput(KVP & current)
{
int c;
while ((c = getchar()) != EOF)
{
if (c == '\t')
parseInput(list .front().sublis t);
else
{
current.key = getkey();
current.value = getvalue();// get the key and value upto and
including the newline...
}
}
}

Of course at some point (the first call to parseInput needs 'this' as a
paramter...
Question is how do i know when to return and pop up to previous level?
When do I push_back the current to the list?
Got any tips or suggestions on how to do this?

Jul 22 '05 #1
9 1479
JustSomeGuy wrote:
I have a class that looks something like this (Don't try to compile it,
I haven't tested this)

class KVP
{
string key;
string value;
list<KVP> sublist;
};

class MyClass
{
private:
list<KVP> list;
public:
void parseInput(void );
};
My input looks something like.

a=b (Where a is the key and b is the value.)
c=e
d=e
b=c
f=g
h=j
k=l

So the number of tabs tells me how deeply nested I am.
I entend to implement this using a stack of KVPs.

void MyClass::parseI nput(KVP & current)
{
int c;
while ((c = getchar()) != EOF)
{
if (c == '\t')
parseInput(list .front().sublis t);
else
{
current.key = getkey();
current.value = getvalue();// get the key and value upto and
including the newline...
}
}
}

Of course at some point (the first call to parseInput needs 'this' as a
paramter...
Question is how do i know when to return and pop up to previous level?
When do I push_back the current to the list?
Got any tips or suggestions on how to do this?


Honestly, I don't see a language problem here. It's a general programming
problem. The only condition that brings it closer to C++ (and similar
languages) is that the language should allow recursion. So, except for
that all you need is some pseudo-code that processes your input.

The input should read an entire line. Then count the tabs and determine
whether it should attempt to add to the sublist (if there more tabs than
the current level) or return (if the number of tabs is the same or less).

This is my attempt at pseudo-code:

void KVP::process_li ne(current_leve l, next_line, source)
begin
key = get_key_from_li ne(next_line)
value = get_value_from_ line(next_line)
while (source.ok())
next_line = source.get_next _line()
new_tabs = number_of_tabs( next_line)
if (new_tabs > current_level)
new_KVP = new KVP
sublist.add(new _KVP);
new_KVP.process _line(current_l evel + 1, next_line, source)
else
return
endif
endwhile
end

Do criticize, please.

V
Jul 22 '05 #2
Victor Bazarov wrote:
JustSomeGuy wrote:
I have a class that looks something like this (Don't try to compile it,
I haven't tested this)

class KVP
{
string key;
string value;
list<KVP> sublist;
};

class MyClass
{
private:
list<KVP> list;
public:
void parseInput(void );
};
My input looks something like.

a=b (Where a is the key and b is the value.)
c=e
d=e
b=c
f=g
h=j
k=l

So the number of tabs tells me how deeply nested I am.
I entend to implement this using a stack of KVPs.

void MyClass::parseI nput(KVP & current)
{
int c;
while ((c = getchar()) != EOF)
{
if (c == '\t')
parseInput(list .front().sublis t);
else
{
current.key = getkey();
current.value = getvalue();// get the key and value upto and
including the newline...
}
}
}

Of course at some point (the first call to parseInput needs 'this' as a
paramter...
Question is how do i know when to return and pop up to previous level?
When do I push_back the current to the list?
Got any tips or suggestions on how to do this?


Honestly, I don't see a language problem here. It's a general programming
problem. The only condition that brings it closer to C++ (and similar
languages) is that the language should allow recursion. So, except for
that all you need is some pseudo-code that processes your input.

The input should read an entire line. Then count the tabs and determine
whether it should attempt to add to the sublist (if there more tabs than
the current level) or return (if the number of tabs is the same or less).

This is my attempt at pseudo-code:

void KVP::process_li ne(current_leve l, next_line, source)
begin
key = get_key_from_li ne(next_line)
value = get_value_from_ line(next_line)
while (source.ok())
next_line = source.get_next _line()
new_tabs = number_of_tabs( next_line)
if (new_tabs > current_level)
new_KVP = new KVP
sublist.add(new _KVP);
new_KVP.process _line(current_l evel + 1, next_line, source)
else
return
endif
endwhile
end

Do criticize, please.

V


Yes Of course you are right I hadn't actually thought of this and not being a
c++ problem.
Where is the 'Take back stupid OT posting' button! :)
Further I wish I could have edited the posting because there are a few errors.

As it stands if you return up to the very top of the 'stack' ie the lowest
recursion level
at then end of each line then you will end up back at the right level
eventually, at which
point you can simply add to the 'end' of that list. Agreed?

Jul 22 '05 #3
JustSomeGuy wrote:
Victor Bazarov wrote:
JustSomeGuy wrote:
I have a class that looks something like this (Don't try to compile it,
I haven't tested this)

class KVP
{
string key;
string value;
list<KVP> sublist;
};

class MyClass
{
private:
list<KVP> list;
public:
void parseInput(void );
};
My input looks something like.

a=b (Where a is the key and b is the value.)
c=e
d=e
b=c
f=g
h=j
k=l

So the number of tabs tells me how deeply nested I am.
I entend to implement this using a stack of KVPs.

void MyClass::parseI nput(KVP & current)
{
int c;
while ((c = getchar()) != EOF)
{
if (c == '\t')
parseInput(list .front().sublis t);
else
{
current.key = getkey();
current.value = getvalue();// get the key and value upto and
including the newline...
}
}
}

Of course at some point (the first call to parseInput needs 'this' as a
paramter...
Question is how do i know when to return and pop up to previous level?
When do I push_back the current to the list?
Got any tips or suggestions on how to do this?


Honestly, I don't see a language problem here. It's a general programming
problem. The only condition that brings it closer to C++ (and similar
languages) is that the language should allow recursion. So, except for
that all you need is some pseudo-code that processes your input.

The input should read an entire line. Then count the tabs and determine
whether it should attempt to add to the sublist (if there more tabs than
the current level) or return (if the number of tabs is the same or less).

This is my attempt at pseudo-code:

void KVP::process_li ne(current_leve l, next_line, source)
begin
key = get_key_from_li ne(next_line)
value = get_value_from_ line(next_line)
while (source.ok())
next_line = source.get_next _line()
new_tabs = number_of_tabs( next_line)
if (new_tabs > current_level)
new_KVP = new KVP
sublist.add(new _KVP);
new_KVP.process _line(current_l evel + 1, next_line, source)
else
return
endif
endwhile
end

Do criticize, please.

V


Yes Of course you are right I hadn't actually thought of this and not being a
c++ problem.
Where is the 'Take back stupid OT posting' button! :)
Further I wish I could have edited the posting because there are a few errors.

As it stands if you return up to the very top of the 'stack' ie the lowest
recursion level
at then end of each line then you will end up back at the right level
eventually, at which
point you can simply add to the 'end' of that list. Agreed?


Which brings me to the C++ question....

If I wish to traverse the list of lists I'm getting syntax errors...

list<KVP> & listref(list); // ie at the beggining I wish to point to the 'head'
of the list.
for (i=0; i < level; ++i) listref = listref.sublist ;

This is were I am getting lost now. I can't get this to compile as it doesn't
seem to like using
refrences using templates...


Jul 22 '05 #4
JustSomeGuy wrote:
[...]
Which brings me to the C++ question....

If I wish to traverse the list of lists I'm getting syntax errors...

list<KVP> & listref(list); // ie at the beggining I wish to point to the 'head'
of the list.
for (i=0; i < level; ++i) listref = listref.sublist ;

This is were I am getting lost now. I can't get this to compile as it doesn't
seem to like using
refrences using templates...


Well, post the actual code, let's see where you get stuck.

For me the following works OK:

#include <list>
using std::list;

struct KVP { int i; list<KVP> sublist; KVP(int i) : i(i) {} };

#include <iostream>
#include <string>

void traverse(KVP& ref, int level) {
std::cout << std::string(lev el, ' ') << ref.i << std::endl;
list<KVP>::iter ator it = ref.sublist.beg in();
while (it != ref.sublist.end ())
traverse(*it++, level + 1);
}

int main() {
KVP root(42);
KVP level1_1(4201), level1_2(4202);
KVP level2_1(420101 ), level2_2(420202 );
level1_1.sublis t.push_back(lev el2_1);
level1_2.sublis t.push_back(lev el2_2);
root.sublist.pu sh_back(level1_ 1);
root.sublist.pu sh_back(level1_ 2);

traverse(root, 0);
}

I filled the structure manually, of course, but the traversal is
recursive as you want.

V
Jul 22 '05 #5

"Victor Bazarov" <v.********@com Acast.net> wrote in message
news:Mv******** *********@newsr ead1.dllstx09.u s.to.verio.net. ..
JustSomeGuy wrote:
[...]
Which brings me to the C++ question....

If I wish to traverse the list of lists I'm getting syntax errors...

list<KVP> & listref(list); // ie at the beggining I wish to point to the 'head' of the list.
for (i=0; i < level; ++i) listref = listref.sublist ;

This is were I am getting lost now. I can't get this to compile as it doesn't seem to like using
refrences using templates...


Well, post the actual code, let's see where you get stuck.

For me the following works OK:

#include <list>
using std::list;

struct KVP { int i; list<KVP> sublist; KVP(int i) : i(i) {} };

#include <iostream>
#include <string>

void traverse(KVP& ref, int level) {
std::cout << std::string(lev el, ' ') << ref.i << std::endl;
list<KVP>::iter ator it = ref.sublist.beg in();
while (it != ref.sublist.end ())
traverse(*it++, level + 1);
}

int main() {
KVP root(42);
KVP level1_1(4201), level1_2(4202);
KVP level2_1(420101 ), level2_2(420202 );
level1_1.sublis t.push_back(lev el2_1);
level1_2.sublis t.push_back(lev el2_2);
root.sublist.pu sh_back(level1_ 1);
root.sublist.pu sh_back(level1_ 2);

traverse(root, 0);
}

I filled the structure manually, of course, but the traversal is
recursive as you want.

V


Ok, this is cool...
I don't know why you declared KVP as a struct and not a class.
(Other than the fact that it won't compile when its a class.)
Why doesn't this work when I declare KVP as a class?



Jul 22 '05 #6
#include <iostream>
#include <list>

using std::list;
using std::string;

struct KVP
{
int i;
list<KVP> sublist;
KVP(int i);
};

KVP::KVP(int i) : i(i)
{
}

int main (int argc, char * const argv[])
{
int c;
KVP root;
KVP &current=roo t;
while ((c=getchar()) != EOF)
{
if (c == '\t')
current = current.sublist .begin(); // This doesn't
work... I assume because I don't have an appropriate operator= defined.
else if (c == '\n')
current = root;
else
current.i=c;
}
return(0);
}

I think this is close to working. Note also that the root isn't a list.
Here I am not using recursion as I have no way of knowing it's time to 'pop'
up a level in recursion.
This might be simple to overcome if I put a period '.' into the input stream
when the stack should be popped.
Jul 22 '05 #7
"JustSomeGu y" <no**@nottellin g.com> wrote...
#include <iostream>
#include <list>

using std::list;
using std::string;

struct KVP
{
int i;
list<KVP> sublist;
KVP(int i);
};

KVP::KVP(int i) : i(i)
{
}

int main (int argc, char * const argv[])
{
int c;
KVP root;
KVP &current=roo t;
while ((c=getchar()) != EOF)
{
if (c == '\t')
current = current.sublist .begin(); // This doesn't
work... I assume because I don't have an appropriate operator= defined.
'current' is a reference. If you are attempting to make it refer to
a differnt object, here is some news: it can't be done. You may need
to rethink 'current'.
else if (c == '\n')
current = root;
else
current.i=c;
}
return(0);
}

I think this is close to working. Note also that the root isn't a list.
Nothing _is_ a list. However, the 'root' and other KVP objects
_have_ lists.
Here I am not using recursion as I have no way of knowing it's time to
'pop'
up a level in recursion.
Take my pseudo-code, loot at it well and translate into C++. Even if
it needs fixing, it is probably fairly close to what you need as far
as recursion is concerned.
This might be simple to overcome if I put a period '.' into the input
stream
when the stack should be popped.


Whatever floats your boat.

Good luck!

V
Jul 22 '05 #8
"JustSomeGu y" <no**@nottellin g.com> wrote in message news:<cn******* ***@news.ucalga ry.ca>...
#include <iostream>
#include <list>

using std::list;
using std::string;

struct KVP
{
int i;
list<KVP> sublist;
The definition of `sublist' is undefined behaviour because
KVP is not completly defined at this point.
It works by accident only.
KVP(int i);
};

KVP::KVP(int i) : i(i)
{
}

int main (int argc, char * const argv[])
{
int c;
KVP root;
KVP &current=roo t;
You are using reference here ...
.... every assignment to `current' will write to `root'!

I guess you should use
KVP* current;
instead.
while ((c=getchar()) != EOF)
{
if (c == '\t')
current = current.sublist .begin(); // This doesn't
work... I assume because I don't have an appropriate operator= defined.
BTW: what if current.sublist is empty?

current = *(current.subli st.begin()); else if (c == '\n')
current = root; .... this is always a self-assignment, most-likley `root' is no more
what it once was!
else
current.i=c;
}
return(0);
}

[snip]

regards,
Stephan Brönnimann
br****@osb-systems.com
Open source rating and billing engine for communication networks.
Jul 22 '05 #9
Stephan Br?nnimann wrote:
"JustSomeGu y" <no**@nottellin g.com> wrote in message news:<cn******* ***@news.ucalga ry.ca>...
#include <iostream>
#include <list>

using std::list;
using std::string;

struct KVP
{
int i;
list<KVP> sublist;

The definition of `sublist' is undefined behaviour because
KVP is not completly defined at this point.
It works by accident only.


It's not a definition. It's a declaration. When the user needs to
create an object of type 'KVP' it will have been completely defined.
[..]


V
Jul 22 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
6856
by: cfanatic | last post by:
Hey all, I been reading through these forums for a long time but have never posted. Well, I got a dillema. I have a program of the Eight Queen's program and I have to make it work without recursion. I have to use a stack instead. It's been buggin me for a week and I have no clue how to start it. Do you guy think you can help me out? Here is the recursive part of the program:
4
5111
by: chandra.somesh | last post by:
I recently was having trouble converting implementaion of recursions using stack. While single level of recursions are quite intuitive , it is when we have more than one recursive calls in the function that the problem arises.Consider for example a simple postorder traversal void post(struct node * p) { if(p==NULL) return;
2
1597
by: jw | last post by:
what is the relation between a stack and recursion func. and if i have recursion funct(a return type void), void print(int n,int base){ static string digits="0123456789abcdef"; if(n>=base){ print(n/base,base); cout<<digits; }
15
2427
by: rover8898 | last post by:
Hello all, I used setjmp() in a recent of program of mine (it is not completed, so I have not the chance to test it out yet). I am not very profocient in C coding as are some of my co-workers. They (my co-workers) say (with vehement ardor ;) ) that the usage of setjmp() emplyoyed in function"C" that was called from function "B" that was called from function "A" that was called form the main(), will cause havoc in the stack. And it makes...
30
2745
by: gaoxtwarrior | last post by:
a sort which is stable means it keeps the object's original order. A sort which is in place is stable. does anyone can explain me what is sort in place? thx.
10
3330
by: elventear | last post by:
Hello everyone, I am runing into recursion limit problems. I have found that the culprit was related to the __hash__ function that I had assigned to the objects that were added to a set. Basically my __hash__ function is the following: def __hash__(self): out_int = 0
2
1457
by: lielar | last post by:
Hi I'm writing a javascript class object that creates objects of itself. Take for example function One(x){ this.x = x; } One.prototype.addOne = function(x) {
8
3938
by: cerise | last post by:
I can't figure out how to make and handle multiple stacks and use them so I could create four linked list stacks representing each suit of cards, one stack each for diamonds, hearts, spades, and clubs. I use objects as my cards. I don't know how to make more than one stack. Can anyone help me out? If I'm not being clear, I'll be happy to clarify the problem I have. here is the class I used to make the Objects for cards, public class...
6
1659
by: Andrew Morton | last post by:
I'm recursing through the controls in an asp.net page to find if any TextBox contains text. JOOI, can I break out of the recursion as soon as it's found one, or does it have to unwind itself? The TextBoxes are generated at run-time. VB.NET 2003, so no Control.FindControl.
0
8996
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
8832
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
9386
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
6799
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6078
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4608
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4879
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
2791
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2217
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.