6. Functions Operating on Arrays or Lists
1. A (push-down pop-up) stack is a data storage unit that has new
information added at the end. When information is removed, it is taken
from that same end. This is also known as a last in, first out stack (LIFO).
The push() function is used in Perl to add data to the end of an
array and the pop() function is used to remove data from the end
of the array.
A (push through) queue is a data storage unit that has new items
at the end, and taking items out from the beginning. This is also known as
first in, first out queue (FIFO).
Whenever any perl program runs, an array called @ARGV is automatically
defined for your use. It holds the value of any command line arguments.
(a). Write a perl program that will output its arguments (make sure to give
it some) in left to right order, as if it is a queue.
(b). Write a perl program that will output its arguments in reverse order
as if it is a stack.
2. Run the following program to see what it outputs.
#! /usr/bin/perl
@heroes = qw(ruth mantle maris)
print "size of \@heroes: ", scalar(@heroes), " "; # print array size
print "highest index: $#heroes "; # print highest array subscript (index)
print ""last element: $heroes[$#heroes]\n\n";
push (@heroes, "sosa");
print "size of \@heroes: ", scalar(@heroes), " "; # print array size
print "highest index: $#heroes "; # print highest array subscript (index)
print ""last element: $heroes[$#heroes]\n\n";
$youngest = pop @heroes;
print "popped the word [$youngest] from \@heroes\n";
print "size of \@heroes: ", scalar(@heroes), " "; # print array size
print "highest index: $#heroes "; # print highest array subscript (index)
print ""last element: $heroes[$#heroes]\n\n";
(a). In the above program, write a simple foreach() loop that would print
the array elements in a readable fashion (lines 3-5).
(b). In the above program, rewrite the last four lines as one print statement
and include a loop to emit the entire contents of the @heroes array.
3. The following program provides names that are in a given order and outputs
them in reverse order.
#! /usr/bin/perl
@players = qw(bob wayne ellen sylvia phil);
$order = 1;
print "Players finished in this order: \n";
foreach $p (@players) {
print $order++, ": $p\n";
push (@drill, $p);
}
print "\n";
$order = 1;
print qq(list them in reverse order: \n);
foreach (@players) {
$next = pop @drill;
print $order++, ": $next\n";
}
(a). Rewrite the program above so that @drill's contents is output in order
instead.
(b). Rewrite the program above so that it uses unshift() to put information
into the stack (into @drill).
4. Run the program Queue1.pl to see what happens.
#! /usr/bin/perl
@heroes = qw(ruth mantle maris)
print "size: ", scalar(@heroes), "\n";
foreach (@heroes) { print "$_ " } print "\n";
push (@heroes, "sosa";)
print "size: ", scalar(@heroes), "\n";
foreach (@heroes) { print "$_ " } print "\n";
$oldest = shift @heroes;
print "shifted the word [$oldest] from \@heroes\n";
print "size: ", scalar(@heroes), "\n";
foreach (@heroes) { print "$_ " } print "\n";
# END OF Queue1.pl
5. Run the following program to see what happens:
#! /usr/bin/perl
@players = qw(bob wayne ellen sylvia phil);
foreach $p (@players) {
print "$p just arrived, adding to list\n";
push (@batters, $player);
}
foreach $batter (0..$#players) {
$next = shift @batters;
print Time for $next to bat/n";
}
(a) There are at least two errors in the above program. What are they?
(b) Rewrite the program to fix the errors.
(c). Would the 2nd foreach line work if written as:
foreach $batter (1..scalar(@players)) {
6. Using the command line arguments array (@ARGV) and a loop, write
a program to print the arguments in reverse order from their left to
right appearance on the command line.
7. Run the following program and see what it does:
#! /usr/bin/perl
@innerdata = qw(
Mercury 57.9 4880
Venus 108.2 12100
Earth 149.6 12756
Mars 227.9 6794
);
print "Here comes the whole array ...\n";
foreach (@innerdata) { print "$_\n"} print "\n";
while ($planet = shift @innerdata) {
$odistance = shift @innerdata;
$diameter = shift @innerdata;
$planetstats = join ":", ($planet, $odistance, $diameter);
push (@ptable, $planetstats);
}
print "Here comes the consolidated table...\n";
foreach (@ptable) { print "$_\n" } print "\n";
(a). On the line where $planetstats is defined, the program pastes
together 3 scalar values into one string. On the second iteration,
what should $planetstats look like after it is executed and before
the push function is executed?
(b). How might the program be rewritten so that the planets
could be sorted according to orbital distance?
8. The splice function takes up to four arguments (The rightmost 2 are
optional: splice (ARRAY, OFFSET, LENGTH, LIST)
If LIST is missing, no elements are substituted and LENGTH elements
are removed starting from the OFFSET. If LENGTH is also missing,
all elements from OFFSET to the end of the array are removed.
Rewrite the program in question 7 to use splice() instead of the 3
shift() statements.
IF IT DOESN'T WORK:
1. (a) one solution is as follows:
#! /usr/bin/;perl
$count = 1;
foreach $arg (@ARGV) {
print $count++, ". $arg\n";
}
(b) one solution is as follows:
#! /usr/bin/perl
while ($arg = pop @argv) {
print "$arg \n";
}
2. In Question 2 (a) One solution is:
foreach (@heroes) { print "$_ "}
print "Array size: ", scalar(@heroes), "\n";
In Question 2 (b) One solution is:
print "
popped the word [$youngest] from \@heroes
size of \@heroes: ",scalar(@heroes),"
highest index: $#heroes
last element: $heroes[$#heroes]\n\n";
3. One solution to Question 3 is:
#! /usr/bin/perl
@players = qw(bob wayne ellen sylvia phil);
$order = 1;
print "Players finished in this order: \n";
foreach $p (@players) {
print $order++, ": $p\n";
unshift (@drill, $p);
}
print "\n";
$order = 1;
print qq(list them in reverse order: \n);
foreach $p (@drill) {
print $order++, ": $p\n";
}
4. In Question 5 (a), The bugs in this program are on line 6,
instead of pushing $p onto the queue, the program pushes
an uninitialized variable $player. The print statement on
line 11 has a forward slash in front of n rather than a \. The
scalar variable $batter is never used.
The program as repaired looks like:
#! /usr/bin/perl
@players = qw(bob wayne ellen sylvia phil);
foreach $p (@players) {
print "$p just arrived, adding to list\n";
push (@batters, $p);
}
foreach (0..$#players) {
$next = shift @batters;
print Time for $next to bat\n";
}
5. In Question 6, one solution is:
#! /usr/bin/perl
while ($a = pop @ARGV) {
print "last argument is $a\n";
}
6. In Question 7, one solution is:
#! /usr/bin/perl
@innerdata = qw(
Mercury 57.9 4880
Venus 108.2 12100
Earth 149.6 12756
Mars 227.9 6794
);
print "Here comes the whole array ...\n";
foreach (@innerdata) { print "$_\n"} print "\n";
while ($planet = shift @innerdata) {
$odistance = shift @innerdata;
$diameter = shift @innerdata;
$planetstats = join ":", ($odistance, $planet, $diameter); #Reorder these
push (@ptable, $planetstats);
}
print "Here comes the consolidated table...\n";
foreach (@ptable) { print "$_\n" } print "\n";
$, = "\n"; # each element of the array on a new line
print "Here comes the sorted table...\n";
print sort { (split ":", $a)[0] <=> (split ":", $b)[0] } @ptable;
print "\n";
print "Sorted by diameter...\n";
print sort { (split ":", $a)[2] <=> (split ":", $b)[2] } @ptable;
print "\n";
7. In Question 8, one solution is:
#! /usr/bin/perl
@innerdata = qw(
Mercury 57.9 4880
Venus 108.2 12100
Earth 149.6 12756
Mars 227.9 6794
);
print "Here comes the whole array ...\n";
foreach (@innerdata) { print "$_\n"} print "\n";
while ( scalar(@innerdata) > 0 ) {
@pdata = splice (@innerdata, 0, 3);
$planetstats = join (":", @pdata);
push (@ptable, $planetstats);
}
print "Here comes the consolidated table...\n";
foreach (@ptable) { print "$_\n" } print "\n";
Questions about the questions? Send mail to Robert Katz: rkatz@ned.highline.ctc.edu
Last Update January 26, 2002