CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: Perl Programming Help: Beginner:
Finding the Max of An Array

 



Northwestern
New User

Oct 21, 2013, 1:56 AM

Post #1 of 13 (1165 views)
Finding the Max of An Array Can't Post

I have a file with two long lists of ordered pairs. I want to find the max of the second list, take the corresponding term in the first list and subtract that value from everything in the first list. My code looks like this:

print "Input FILE NAME";
$filename = <STDIN>;
open (FILE1, "$filename");
open (FILE2, ">RESULTS_FILE.txt");

while ($x = <FILE1>) {
chomp $x;
@x = split(/\s+/, $x);
$time = $x[0];
$intensity = $x[1];
$i=0;
for ($i<=$intensity[-1]) {
if $intensity[$i+1] > $intensity[$i] {
$max = $time[$i+1];
}
else {
$max = $time[$i];
}
$i++;
}
$new_time = $time - $max;

then I do some math, close the while loop and print the results. I get these errors:


syntax error at ./world.pl line 39, near "if $intensity"
syntax error at ./world.pl line 42, near "else"
syntax error at ./world.pl line 46, near "}"
syntax error at ./world.pl line 71, near "}"

I haven't used perl since summer, nor have I ever been the greatest programmer. Could anyone help me out?


Laurent_R
Veteran / Moderator

Oct 21, 2013, 11:01 AM

Post #2 of 13 (1153 views)
Re: [Northwestern] Finding the Max of An Array [In reply to] Can't Post

First, $intensity is a scalar:

Code
$intensity = $x[1];

And then, you are using it as an array:

Code
$intensity[-1]

The conditional should be between parens:

Code
if $intensity[$i+1] > $intensity[$i] {

should be:

Code
if ($intensity[$i+1] > $intensity[$i]) {

(in addition to what I already said about $intensity).

There are many other errors, but that should alreadfy help you get going.


Kenosis
User

Oct 21, 2013, 12:47 PM

Post #3 of 13 (1149 views)
Re: [Northwestern] Finding the Max of An Array [In reply to] Can't Post

Perhaps the following algorithm will be helpful:

Code
use strict; 
use warnings;

my ( @col1Vals, $col2Max );

while (<DATA>) {
my ( $col1, $col2 ) = split;
$col2Max = $col2 if !defined $col2Max or $col2 > $col2Max;
push @col1Vals, $col1;
}

print "Col2 max val: $col2Max\n";

my @adjustedCol1Vals = map { $_ - $col2Max } @col1Vals;
print "$_\n" for @adjustedCol1Vals;

__DATA__
125 17
214 35
267 99
371 71
156 19

Output:

Code
Col2 max val: 99 
26
115
168
272
57

As your script did, the above splits each line to get the two column-values. Next, it updates the variable $col2Max with the greatest column-two value encountered, and then pushes the column-one value onto an array for later.

When the file's processed, map is used to transform the column one values into a set whose members all had $col2Max subtracted from them. Finally, the adjusted values are printed.


(This post was edited by Kenosis on Oct 21, 2013, 1:25 PM)


zapzap
User

Oct 23, 2013, 1:51 AM

Post #4 of 13 (1116 views)
Re: [Kenosis] Finding the Max of An Array [In reply to] Can't Post

Kenosis, as far as readability and clarity, yours is very good.

After seeing this I thought I would try using map a lil more, similar to the Schwartzian transform.

I couldn't avoid having to pick out the max. I tried to group the last map with the others but I couldn't figure out a way to do something like

Code
 
map { max = $_->[1];
$_->[0] - max } input

without the map resetting max each time.....I hope I make sense.

Anyways here is my alternate version

Code
 
my @data = map { [split(/\s+/,$_->[0])] }
sort { $b->[1] <=> $a->[1] }
map { [$_, (split(/\s+/))[1]] } <DATA>;

print "Column 2 maximum value: " . $data[0]->[1] . "\n",
map {"Original: " . $_->[0]," Modifed: ", $_->[0] - $data[0]->[1],"\n"} @data;

##OUTPUT
Column 2 maximum value: 99
Original: 267 Modifed: 168
Original: 371 Modifed: 272
Original: 214 Modifed: 115
Original: 156 Modifed: 57
Original: 125 Modifed: 26


Maybe someone else can clean my code up? Gooday


Laurent_R
Veteran / Moderator

Oct 23, 2013, 12:09 PM

Post #5 of 13 (1101 views)
Re: [zapzap] Finding the Max of An Array [In reply to] Can't Post

Sorting an array to find the max is overkill. Don't do that unless you have only a few elements.

The code is basically clean, but the algorithm stinks.


BillKSmith
Veteran

Oct 23, 2013, 12:38 PM

Post #6 of 13 (1097 views)
Re: [zapzap] Finding the Max of An Array [In reply to] Can't Post


Quote
I have a file with two long lists of ordered pairs. I want to find the max of the second list, take the corresponding term in the first list and subtract that value from everything in the first list. My code looks like this:


This sounds like you should be subtracting 267, not 99.
Good Luck,
Bill


Laurent_R
Veteran / Moderator

Oct 23, 2013, 1:59 PM

Post #7 of 13 (1093 views)
Re: [BillKSmith] Finding the Max of An Array [In reply to] Can't Post

No, 99 might be the max value of comumn 2 which sgould therefore be subtracted from values in column 1.

To the OP: can you please a short sample of data and the result you are expecting? That would be clearer.


Laurent_R
Veteran / Moderator

Oct 23, 2013, 2:41 PM

Post #8 of 13 (1087 views)
Re: [zapzap] Finding the Max of An Array [In reply to] Can't Post

Since you seem to be willing to store your whole file into an array, I'll assume your data is not too big for your memory. This is my modified version of your program, using two maps but avoiding the overhead of a useless sort:


Code
my $max = O; # this assumes at least one value is larger than 0 
my @data = map { my @pair = split /\s+/ ; $max = $pair[1] if $pair[1] > $max; \@pair} <DATA>;
print "Max value = $max\n";
print map {"Original = $_->[0], modified = " . ($_->[0] - $max) . "\n"} @data;

__DATA__
170 24
120 67
140 12
190 17
234 67
69 12


Output:

Code
$ perl  two_cols.pl 
Max value = 67
Original = 170, modified = 103
Original = 120, modified = 53
Original = 140, modified = 73
Original = 190, modified = 123
Original = 234, modified = 167
Original = 69, modified = 2


Less code, and this will most probably be significantly faster if the data set is large.


BillKSmith
Veteran

Oct 23, 2013, 7:55 PM

Post #9 of 13 (1077 views)
Re: [Laurent_R] Finding the Max of An Array [In reply to] Can't Post

99 is the max value in column two. I would like to see ZAPZAP reconcile this with my emphasis in post #6.
Good Luck,
Bill


zapzap
User

Oct 24, 2013, 1:32 AM

Post #10 of 13 (1071 views)
Re: [Laurent_R] Finding the Max of An Array [In reply to] Can't Post

Nice work there Laurent! You're right, I shouldn't need to sort the data. But this is not my 'data'. Thank you for submitting your proposal instead of simply noting my 'algorithm stinks'.

It looks like you stored your results in an array as well as I did and the person before myself did.

Gooday


zapzap
User

Oct 24, 2013, 1:38 AM

Post #11 of 13 (1070 views)
Re: [BillKSmith] Finding the Max of An Array [In reply to] Can't Post

Northwestern should step in to clarify. Bill I see your point.
Gooday


Laurent_R
Veteran / Moderator

Oct 24, 2013, 12:15 PM

Post #12 of 13 (1064 views)
Re: [zapzap] Finding the Max of An Array [In reply to] Can't Post


In Reply To
Nice work there Laurent! You're right, I shouldn't need to sort the data. But this is not my 'data'. Thank you for submitting your proposal instead of simply noting my 'algorithm stinks'.

It looks like you stored your results in an array as well as I did and the person before myself did.


Hmm, sorry, I mixed you up with the OP.

I used an array to store the data only because I wanted to keep as close as possible to your solution, just changing what I thought needed to be changed in terms of basic algorithm.

As for the "stinking" algorithm, sorry about that, nothing personal, I did not want to be derogatory, but just to say that sorting the data to find the smallest or largest value can be a huge performance overhead if the data set is large. When I wrote that message, I did not have enough time to fully elaborate, but, as you know, I came back later to give a possible alternate solution.

I am working daily with really huge dataset (dozens of GB), so, I would usually avoid loading data into an array but prefer to iterate over the file (even doing it twice if necessary), but when I know for sure that the data is going to be small, I have no problem with loading such data into memory if it will buy me some other advantage.


zapzap
User

Oct 25, 2013, 11:06 AM

Post #13 of 13 (1050 views)
Re: [Laurent_R] Finding the Max of An Array [In reply to] Can't Post

Thanx for your clarification. Gooday

 
 


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives