473,625 Members | 3,318 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Detecting Recursion

Hi,

Say I have an array containing a reference to itself:
$myArray = array();
$myArray['self'] =& $myArray;
How can I, looping iteratively through the array, detect the fact that
$myArray['self'] will "take" me to where I have already been? The print_r()
and var_dump() functions print *RECURSION* in such a case (though only after
the "second round"). Setting a flag seems to be the only solution, but I
don't want to modify the array in question - I want to produce a visual
representation of its contents like var_dump(), but formatted to my taste. I
had considered parsing the output of var_dump(), but first, that format
might change in a future version of PHP and second, an array key might be a
string resembling part of the output (like $myArray['["myArray"]=>']), which
seems to be difficult to detect by the parsing code.

Is there another way of doing this?

Greetings,
Thomas
Oct 18 '05 #1
6 4210
Hi Thomas,

Generally, for recursion detection you use a "Set". You use a either
breadth first search or a depth first search algorithm to go through the
graph of data structures, collection and/or objects and put every node
into the Set (google for these algorithms, or for backtracking
algorithm). Before every next step you also check if the next node is
already in the Set. The Set can answer this question very fast becuase
it uses Hashing. If it is in the set, skip it.

Your problem: php has no Set. But you can use an associative array and
add unique keys for each node, with some not-null value as value.
Something like this:
$visitedKeys[getUniqueKey($n ode)] = true;
Now you can check wheather the node was already visited by:
isSet($visitedK eys[getUniqueKey($n ode)])
I bet associative arrays use hasing, just like Sets (lookup is so fast).
Of course you do have to program the getUniqueKey function to work with
your actual data ;-)

Greetings,

Henk Verhoeven,
www.phpPeanuts.org

Thomas Mlynarczyk wrote:
Hi,

Say I have an array containing a reference to itself:
$myArray = array();
$myArray['self'] =& $myArray;
How can I, looping iteratively through the array, detect the fact that
$myArray['self'] will "take" me to where I have already been? The print_r()
and var_dump() functions print *RECURSION* in such a case (though only after
the "second round"). Setting a flag seems to be the only solution, but I
don't want to modify the array in question - I want to produce a visual
representation of its contents like var_dump(), but formatted to my taste. I
had considered parsing the output of var_dump(), but first, that format
might change in a future version of PHP and second, an array key might be a
string resembling part of the output (like $myArray['["myArray"]=>']), which
seems to be difficult to detect by the parsing code.

Is there another way of doing this?

Greetings,
Thomas

Oct 18 '05 #2
Also sprach Henk Verhoeven:
Your problem: php has no Set. But you can use an associative array and
add unique keys for each node, with some not-null value as value.
Something like this:
$visitedKeys[getUniqueKey($n ode)] = true;
Now you can check wheather the node was already visited by:
isSet($visitedK eys[getUniqueKey($n ode)])


Thank you for your suggestion. The only problem is the getUniqueKey()
function. The only way I can think of is adding another special index to
each (sub-)array, but then I would a) modify the array and b) still not know
how to find a suitable key name (must be the same for all and one that is
not used in the tree structure). It is not possible to directly access the
symbol table?

Greetings,
Thomas
Oct 19 '05 #3
Thomas,

Maybe debug_zval_dump () can be of use for getting an unique key? See
http://www.php.net/manual/en/functio...-zval-dump.php
(the part about refcount is confusing, but maybe you do only need the
first (string(11)) part of the output)

Greetings,

Henk Verhoeven,
www.phpPeanuts.org.

Thomas Mlynarczyk wrote:
Also sprach Henk Verhoeven:

Your problem: php has no Set. But you can use an associative array and
add unique keys for each node, with some not-null value as value.
Something like this:
$visitedKey s[getUniqueKey($n ode)] = true;
Now you can check wheather the node was already visited by:
isSet($visite dKeys[getUniqueKey($n ode)])

Thank you for your suggestion. The only problem is the getUniqueKey()
function. The only way I can think of is adding another special index to
each (sub-)array, but then I would a) modify the array and b) still not know
how to find a suitable key name (must be the same for all and one that is
not used in the tree structure). It is not possible to directly access the
symbol table?

Greetings,
Thomas

Oct 20 '05 #4
Also sprach Henk Verhoeven:
Maybe debug_zval_dump () can be of use for getting an unique key? See
http://www.php.net/manual/en/functio...-zval-dump.php
(the part about refcount is confusing, but maybe you do only need the
first (string(11)) part of the output)


An interesting function - especially because of the refcount. I do not quite
see yet how I could use it for getting a unique key (the point being to get
different values for different things even if they are identical copies),
but I will have a closer look at this function. Thanks for the suggestion.

Greetings,
Thomas
Oct 21 '05 #5
Thomas,

If the reference count does not help you, I think you have two options
here:

1) under each non-unique key, put another array and put all copies in
that array. To check if a node is already visited, get its key, then
search sequentially through the array that is under the key to see if
one of the nodes in there is identical to the currently visited one.
However, you need a way to distinguish copies from references. AFAIK you
can only do this in php4 by changing the value of one variable and see
if the other variable changes too. But then you have to put (or change)
the original value back, and all this without copying (i have not
figured out how to do that, don't know if it can be done at all). In php
5 you can use === with objects, but not with arrays. Of course if you
have many copies of some of the nodes, the sequential searching can
become very resource-consuming (exponentially slower with the number of
copies of the same node).

2) *make* the copies different. As described on the manual page, values
that are formally copies are actually kept as references as long as they
are unchanged. Assuming only arrays and objects can serve as nodes in
the graph, if you can change each node and then change it back to its
original state, php will create a real copy for each, and probably not
undo that if you change it back to its original state. Real copies
probably have different first parts of the debug_zval_dump () values. So
after you have modified each node, you can store its unique key for
lookup to detect recursion. Of course this will be expensive (slow) if
there are many copies to be "realized", but the slowdonwn will be liniar
with the number of copies to realize, so with large searches with many
copies of the same node this will be a lot faster then option 1)

Maybe you can even combine these strategies, but that may complicate
things more then you like.

Hope this helps.

Greetings,

Henk Verhoeven,
www.phpPeanuts.org.

Thomas Mlynarczyk wrote:
Also sprach Henk Verhoeven:

Maybe debug_zval_dump () can be of use for getting an unique key? See
http://www.php.net/manual/en/functio...-zval-dump.php
(the part about refcount is confusing, but maybe you do only need the
first (string(11)) part of the output)

An interesting function - especially because of the refcount. I do not quite
see yet how I could use it for getting a unique key (the point being to get
different values for different things even if they are identical copies),
but I will have a closer look at this function. Thanks for the suggestion.

Greetings,
Thomas

Oct 23 '05 #6
Also sprach Henk Verhoeven:
1) under each non-unique key, put another array and put all copies in
that array. To check if a node is already visited, get its key, then
search sequentially through the array that is under the key to see if
one of the nodes in there is identical to the currently visited one.
Sounds like a lot of trouble for a recursion check. :-(
However, you need a way to distinguish copies from references.
Ay, there's the rub.
you can only do this in php4 by changing the value of one variable
and see if the other variable changes too.
Actually, I'd have to check more or less *all* variables to see if there's
one that changes accordingly.
In php 5 you can use === with objects,
Like "===" would mean "is_referen ce" and "!==" would mean "is_copy"? That's
great news! :-)
but not with arrays.


I knew there was a catch... :-(

Hm, so it seems there is no real quick & easy solution for this problem. For
the moment, I think I will stick with a workaround: Limiting the maximum
nesting level while going through the data. At least this will prevent
system hangs. Later I can try to improve my script using your suggestions.

Thanks again for your help!

Greetings,
Thomas
Oct 26 '05 #7

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

Similar topics

5
3414
by: Peri | last post by:
I'm trying to create Python parser/interpreter using ANTLR. Reading grammar from language refference I found: or_expr::= xor_expr | or_expr "|" xor_expr For me it looks like infinite recursion. And so it says ANTLR. Maybe I don't understand EBNF notation. For me it should look like this. or_expr::= xor_expr | xor_expr "|" xor_expr and in ANTLR grammar file like this:
12
2749
by: da Vinci | last post by:
Greetings. I want to get everyone's opinion on the use of recursion. We covered it in class tonight and I want a good solid answer from people in the "know" on how well recursion is accepted in modern day applications. Should we readily use it when we can or only when absolutly forced to use it?
43
4146
by: Lorenzo Villari | last post by:
I've tried to transform this into a not recursive version but without luck... #include <stdio.h> void countdown(int p) { int x;
2
1562
by: Csaba Gabor | last post by:
I suppose spring fever has hit at alt.math.undergrad since I didn't get any rise from them when I posted this a week ago, so I am reposting this to some of my favorite programming groups: I'm looking for problems that have double (or more) recursion, where the split is not clean (ie. where there may be overlap). Let's call this overlapped recursion, where the
75
5597
by: Sathyaish | last post by:
Can every problem that has an iterative solution also be expressed in terms of a recursive solution? I tried one example, and am in the process of trying out more examples, increasing their complexity as I go. Here's a simple one I tried out: #include<stdio.h> /* To compare the the time and space cost of iteration against
18
3713
by: MTD | last post by:
Hello all, I've been messing about for fun creating a trial division factorizing function and I'm naturally interested in optimising it as much as possible. I've been told that iteration in python is generally more time-efficient than recursion. Is that true? Here is my algorithm as it stands. Any suggestions appreciated!
13
4516
by: robert | last post by:
My code does recursion loops through a couple of functions. Due to problematic I/O input this leads sometimes to "endless" recursions and after expensive I/O to the Python recursion exception. What would be a good method to detect recursion loops and stop it by user-Exception (after N passes or some complex criteria) without passing a recursion counter parameter through all the funcs? Robert
20
2981
by: athar.mirchi | last post by:
..plz define it.
35
4712
by: Muzammil | last post by:
int harmonic(int n) { if (n=1) { return 1; } else { return harmonic(n-1)+1/n; } } can any help me ??
0
8694
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
8356
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
8497
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
6118
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
5570
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
4089
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
4193
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
2621
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
1500
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.