Showing nested for loops in a flowchart - loops

How could I show a nested loop in a flowchart?
I want to show a nested foreach loop in a flowchart that shows something like this
foreach($array as $item) {
foreach($SecondArray as $key=>$value) {
// Do stuff...
}
}
Now correct me if I'm wrong, but there is no way to show a foreach loop in a flowchart, so I'd need to show a for loop in the diagram(?) So the algorithm should be shown as something more like:
for ($i = 0; $i < count($array); i++) {
for ($j = 0; $j < count($arrayTwo); $j++) {
// Do stuff...
}
}
Now looking at the answers to this question (How to picture “for” loop in block representation of algorithm), a single for loop could be shown like this:
But I cannot think of any way in which I could show a nested loop (to show the code I wrote above).
Any suggestions?

This is what you are looking for.
You can see other interesting flowchart for nested loops here.

Related

PHP Undefined offset: -1, how can I skip the negative index?

I already have a program in java which works fine. I tried writing the same one in php and got to some errors.
For example, in this code
for ($i=0; $i<64; $i++) {
$r=$i/8;
$c=$i%8;
$temp=1;
for ($j=-1; $j<=1; $j+=2) {
for ($k=-1; $k<=1; $k+=2) {
while(" " == $chessBoard[$r+$temp*$j][$c+$temp*$k])
{
//some other code here
}
}
}
}
$chessBoard is a two dimensional array
$chessBoard= array
(
array("r","k","b","q","a","b","k","r"),
array("p","p","p","p","p","p","p","p"),
array("0","0","0","0","0","0","0","0"),
array("0","0","0","0","0","0","0","0"),
array("0","0","0","0","0","0","0","0"),
array("0","0","0","0","0","0","0","0"),
array("P","P","P","P","P","P","P","P"),
array("R","K","B","Q","A","B","K","R")
);
I know that the error happens when I'm trying to access $chessBoard[$r+$temp*$j][$c+$temp*$k] when for example $r is 0 and $j is -1, then I get 0+1*-1 which is -1, but I don't know how to get rid of this problem and still have the program to work properly. It's still not clear to me why I didn't have the same problem in java.
Before the code
while(" " == $chessBoard[$r+$temp*$j][$c+$temp*$k])
{
//some other code here
}
put in:
if($r+$temp*$j < 0 || $c+$temp*$k) continue;
This will go to the next iteration of the for-loop and will not run into any indexoutofboundsexception

Perl: Use of reference "HASH(0x13bd718)" as array index at

I'm writing a script to implement game 2048 to practice perl, and an error pops up occationally as something like this:
Use of reference "HASH(0x13bd718)" as array index at 2048.pl line 181, line 11.
The code involved is for a subroutine like this:
sub gen1{
my #free_locs = {};
my $length;
my $rand_loc;
my $insert_loc;
for ($i=0; $i<16; $i++){
if($all_lines[$i] == 0){push #free_locs, $i;}
}
$length = #free_locs;
$rand_loc = int rand $length;
if ($rand_loc == $length) {$rand_loc--;}
$insert_loc = $free_locs[$rand_loc];
$all_lines[$insert_loc] = &generate();
&row_update;
&col_update;
}
At first I was writing that like as
$all_lines[$free_locs[$rand_loc]] = &generate();
The error seems to pop up more often. Then I switched to the code in the subroutine shown above, which seems to reduce the chance for it to happen, but it still happens...
Is there anything wrong with my way of coding here? What's the cleanest way of writing such piece of code?
Thanks and regards,
Terry
my #free_locs = {}; declares #free_locs to be a one-element array whose first element is a reference to an empty hash ({}). Thus, whenever $rand_loc is 0, $insert_loc will be a hash, and trying to use that hash as an index in $all_lines[$insert_loc] produces the error. To declare #free_locs as an empty array, write either my #free_locs = (); or just my #free_locs;.

inserting numeric results of a function into perl array using a for loop

i am new to perl and i want to do something similar to what i do in C.
for(i=0;i<32;i++)
{
array[i]= some_function_result();
}
and then print the array
and for doing this, what i am trying to do in perl is
#data=();
for($i=0;$i<32;$i++){
$hexval = unpack('H2',substr($payload,$i,1));
#data[$i]=$hexval;
}
print #data;
is this correct?
i tried to use the functions like push(#data,$hexval) but that resulted in
32
64
96...
i know this is naive..but can someone help me out with this please..
int i;
for (i=0; i<32; i++) {
array[i]= some_function_result();
}
is
for (my $i=0; $i<32; $i++) {
$array[$i] = some_function_result();
}
or better yet
for my $i (0..31) {
$array[$i] = some_function_result();
}
Flow control statements are documented in perlsyn.
Variable types are documented in perldata.
(Accessible using perldoc perlsyn or even man perlsyn.)
You should indeed always use use strict; use warnings;.

Perl Modification of non creatable array value attempted, subscript -1

I have a Perl-Script, which executes a recursive function. Within it compares two elements of a 2dimensional Array:
I call the routine with a 2D-Array "#data" and "0" as a starting value. First I load the parameters into a separate 2D-Array "#test"
Then I want to see, if the array contains only one Element --> Compare if the last Element == the first. And this is where the Error occurs: Modification of non creatable array value attempted, subscript -1.
You tried to make an array value spring into existence, and the subscript was probably negative, even counting from end of the array backwards.
This didn't help me much...I'm pretty sure it has to do with the if-clause "$counter-1". But I don't know what, hope you guys can help me!
routine(#data,0);
sub routine {
my #test #(2d-Array)
my $counter = $_[-1]
for(my $c=0; $_[$c] ne $_[-1]; $c++){
for (my $j=0; $j<13;$j++){ #Each element has 13 other elements
$test[$c][$j] = $_[$c][$j];
}
}
if ($test[$counter-1][1] eq $test[-1][1]{
$puffertime = $test[$counter][4];
}
else{
for (my $l=0; $l<=$counter;$l++){
$puffertime+= $test[$l][4]
}
}
}
#
#
#
if ($puffertime <90){
if($test[$counter][8]==0){
$counter++;
routine(#test,$counter);
}
else{ return (print"false");}
}
else{return (print "true");}
Weird thing is that I tried it out this morning, and it worked. After a short time of running he again came up with this error message. Might be that I didn't catch up a error constellation, which could happen by the dynamic database-entries.
Your routine() function would be easier to read if it starts off like this:
sub routine {
my #data = #_;
my $counter = pop(#data);
my #test;
for(my $c=0; $c <= $#data; $c++){
for (my $j=0; $j<13;$j++){ #Each element has 13 other elements
$test[$c][$j] = $data[$c][$j];
}
}
You can check to see if #data only has one element by doing scalar(#data) == 1 or $#data == 0. From your code snippet, I do not see why you need to copy the data to passed to routine() to #test. Seems superfluous. You can just as well skip all this copying if you are not going to modify any of the data passed to your routine.
Your next code might look like this:
if ($#test == 0) {
$puffertime = $test[0][4];
} else {
for (my $l=0; $l <= $counter; $l++) {
$puffertime += $test[$l][4];
}
}
But if your global variable $puffertime was initialized to zero then you can replace this code with:
for (my $l=0; $l <= $counter; $l++) {
$puffertime += $test[$l][4];
}

Comparing two associative arrays

I started learning Perl last week.
I have an associative array from a file containing 'tokens' - Just a bunch of numbers.
I have another associative array from an SQL Database containing 'tokens'.
I'm wanting to see if any tokens in the file are NOT in the database. However anything I do doesn't seem to work and I've come to the conclusion that I'm just confusing myself.
I'm not sure I fully understand associative arrays yet but this is a snippet of my code for the file hash:
while($row = <FILE>){
if($row =~ /^000\E/){
#tmp=split(/\s+/,$row);
if($tmp[1] ne "Unassigned"){
$tokenfile{$tmp[0]} = $tmp[1] . " " . $tmp[2];
}
}
}
$tmp[1] + $tmp[2] are the first and second names. I compare names later on to see if they equal each other. However I want to compare $tmp[0] - The token. This is the SQL hash:
while(#rows = $sth->fetchrow_array){
($name, $passwd, $uid, $gid, $quota, $comment, $gcos, $dir, $shell) = getpwnam("\L$rows[1]\E");
$gcos =~ s/,.*//;
if(!defined($gcos)){
$missing++;
$tokendb{$rows[0]} = $rows[1];
}
else{
$tokendb{$rows[0]} = $gcos;
}
}
$rows[0] is the token.
I assumed I would use two foreach loops such as this:
foreach $token (keys(%tokendb)) {
foreach $token2(keys(%tokenfile)){
if($token ne $token2){
print "$token2 NOT IN DATABASE\n";
}
}
}
But that gives me the result of a lot of values that are still in the database.
I'd love some hints as to why this isn't working. Very frustrating as I know it's something so simple but my brain isn't working so well today (Even though it's my 21st Birthday :|).
foreach $token (keys(%tokenfile)) {
if (! exists $tokendb{$token}) {
print "$token NOT IN DATABASE\n";
}
}
Your nested loop failed because even if a key exists, it doesn't match all the other keys. To do it with a nested loop, it should be:
foreach $token (keys(%tokenfile)) {
$found = 0;
foreach $token2 (keys(%tokendb)) {
if ($token eq $token2) {
$found = 1;
last;
}
}
if (!found) {
print "$token NOT IN DATABASE\n";
}
}
Of course, there's no reason to write it this way, this is just to help you understand how your logic failed.
If you're iterating over a hash and testing every key individually to see whether one of them is a target value, then you're not taking advantage of the power of hashes: Lookups. Try something like
foreach $token (keys(%tokenfile)) {
unless (exists $tokendb{$token}) {
print "$token NOT IN DATABASE\n";
}
}
instead.

Resources