Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw

Recursive loops

by reaper9187 (Scribe)
on Dec 11, 2012 at 07:09 UTC ( #1008221=perlquestion: print w/replies, xml ) Need Help??
reaper9187 has asked for the wisdom of the Perl Monks concerning the following question:

HI monks... i have a problem i need help with .. Its more of a problem related to general programming... i'm trying to use recursion for a problem .. the structure of the program is like this ..

I'm importing certain set of values (stored in an array, say X) from a subroutine... I need to perform two checks .. say subA,subB.

For each of the values in set X, i perform a check using sub A and then assign values using subB. we then perform the check using new (updated)values of elements and perform checks and eliminate some values and then assign new values using subB. We do this repeatedly till none are left.

Since there involves updating and re-checking in the process, is there some way we can do this recursively ??

I was thinking of something on the lines
foreach $key(@X) { &subA($key); #returns the result of check, if yes then #assign new values else ignore &subB; #subA returns an array of elements whose values #need to be reassigned. subB then assigns value }
Is there a better way to do this or am i treading on the right path ??

Replies are listed 'Best First'.
Re: Recursive loops
by dsheroh (Prior) on Dec 11, 2012 at 08:38 UTC
    Why jump to recursion? I don't see any reason for it in your post. Personally, I'd use a queue for this:
    my @queue = (1, 2, 3, 4); while (@queue) { my $current = shift @queue; next unless subA($current); push @queue, subB($current); }
    (And don't get in the habit of prefixing your sub calls with &. It's not required in Perl 5+ and has side-effects that you probably don't expect.)
Re: Recursive loops
by roboticus (Chancellor) on Dec 11, 2012 at 12:05 UTC


    None of this hand-wavy stuff is helpful at all. If you want to know if recursion is appropriate for your problem, don't look at the structure of your code--look at the structure of your problem.

    Going to the basics: If you can express your problem as a solution to a degenerate case or a transformation on a smaller version of the same problem, then you can generally solve it with recursion. (Whether it's the best method of solution is still undetermined, though.).

    For a contrived version, suppose you wanted to find out how many vowels are in a string. A stupid recursive solution could be done like so:

    my $t='the quick red fox jumped over the lazy brown dog'; print count_vowels($t); sub count_vowels { my $string = shift; # Check degenerate case: a single character string. if (length($string) == 1) { return 1 if $string =~ /a|e|i|o|u/i; return 0; } # Break the problem into two smaller problems: my ($part1, $part2) = (substr($string,0,1), substr($string,1) ); return count_vowels($part1) + count_vowels($part2); }

    Note: Yes, I've oversimplified a bit.


    When your only tool is a hammer, all problems look like your thumb.

Re: Recursive loops
by TJPride (Pilgrim) on Dec 11, 2012 at 10:43 UTC
    Rather than stating your problem in theoretical generalities, it might be more helpful to give us a sample of your input data, desired output data, and specifically what you're checking for and replacing with. That way we can be sure the correct approach is given to you.
Re: Recursive loops
by bimleshsharma (Beadle) on Dec 11, 2012 at 07:15 UTC

    If you provide definition of both subroutines then only anybody can know this is recursive or not and can say better or worst way to do thit. Current structure does't say it is recursive loop.

Re: Recursive loops
by reaper9187 (Scribe) on Dec 11, 2012 at 11:44 UTC
    The actual subroutines are very long and perform comprehensive checks.... I can , however, give you some sample data


    I have an array @array = (A,B,C,D,E,F) (these values are again picked up from another subroutine .so i have no control over its size.) For the elements in the array I perform a check (using sub A) and assign values(using sub B , say A=1, B=2 , C=4 etc) .. I then use these updated values to perform a specific check(using subA). Assume that i need to change the value for A,B again (using B). This is done iteratively done till i observe no clash

    So the input is something like @array = (A,B,C,D,E..) Process;
    1. Perform using sub A
    2. Assign values using B
    O/p after first iteration : A= 1, B = 2 , C = 2, D= 4, E= 5;
    3.Check again using A
    -Assuming I need to change the values for C, D.
    4.Assign values using B
    5.Check again using A. If no faults detected, break out of loop

    The final o/p would look like A= 1, B= 2,C = 3,D =4,....
    Note that the above is jus an example of the process flow and not the actual data.
      In that case, you don't even need a queue. To restate your description of the process:
      While subA detects faults, use subB to correct them.
      Translating this to Perl is trivial:
      while (subA(@array)) { subB(@array); }
      while (my @faults = subA(@array)) { subB(\@array, \@faults); }
      if subB needs to know what the list of faults was.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1008221]
Approved by davido
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others imbibing at the Monastery: (5)
As of 2017-03-25 18:03 GMT
Find Nodes?
    Voting Booth?
    Should Pluto Get Its Planethood Back?

    Results (311 votes). Check out past polls.