RE: Re: All array elements the same?
by jjhorner (Hermit) on Aug 01, 2000 at 20:28 UTC
|
Okay, you threw me on this one. Could someone please
explain the above code. I am completely lost!
J. J. Horner
Linux, Perl, Apache, Stronghold, Unix
jhorner@knoxlug.org http://www.knoxlug.org/
| [reply] |
|
It does the job tho' :)
Ok. With comments...
# define a hash to count the unique elements in @arr
my %check;
# @check{@arr} is a hash slice. It gives to all of the
# values in %check where the key is an element from @arr.
# This is a list and it's also an lvalue (i.e. you can
# assign values to it.
#
# (1) x @arr (and I've corrected this from the original
# version. Uses the 'x' operator as a list constructor.
# In a list context it creates a list containing its
# left operand repeated the number of times given by
# the right operand (which is a scalar). @arr in a scalar
# context gives the number of elements in @arr. Hence
# we get a list containing scalar(@arr) 1s.
#
# We then assign this list to the list of lvalues created
# by @check{@arr}. This assigns a 1 to each value associated
# with a key found %check. The keys of %check are given by
# @arr, therefore we effectively create a key/value pair
# in %check for each element of @arr where the key is the
# element of @arr and the value is 1. If any element of
# @arr occurs multiple times we assign to the relevant
# value in %check multiple times.
#
# We can then use 'keys' to extract this list of keys. If
# all the elements of @arr are the same the list of keys
# in %create only has one element.
@check{@arr} = (1) x @arr;
print "All the same" if keys %check == 1;
Does that help?</code>
--
<http://www.dave.org.uk>
European Perl Conference - Sept 22/24 2000, ICA, London
<http://www.yapc.org/Europe/> | [reply] [d/l] |
|
He's putting all the elements of the array into a hash,
using a hash slice @check{@arr} = @arr x 1;
Then, if there is only one key, all the values must have
been identical.
@check{@arr} is the "keys" part of the slice, and
@arr x 1 just gives us the correct number of
"values."
Voila! A list of the unique elements of @arr (in keys
%check). If there is only one unique element, then
they are all the same. Two problems solved for the price
(two lines, in this case) of one. :-)
Russ
Brainbench 'Most Valuable Professional' for Perl
| [reply] |
|
J. J. Horner
Linux, Perl, Apache, Stronghold, Unix
jhorner@knoxlug.org http://www.knoxlug.org/
| [reply] |
RE: Re: All array elements the same?
by BlaisePascal (Monk) on Aug 01, 2000 at 22:23 UTC
|
Thanks, that solved a different problem that I had...
Given formal parameter list @params, and argument list @args, how do you get %table such that $table{$param[i]} eq $args[i].
Solution: @table{@params} = @args;
That'll eliminate a subroutine or two in my current project...
| [reply] [d/l] [select] |
RE: Re: All array elements the same?
by Fastolfe (Vicar) on Aug 01, 2000 at 22:25 UTC
|
You don't usually need the (1) x @arr when doing stuff like this. This would suffice perfectly:
@check{@array_to_test} = (); # Sets them all to undef
$all_the_same = (keys %check <= 1); # empty @ary = true too? heck, wh
+y not?
If you were checking a true/false condition based on the presence of any of the keys, the 1 would be needed, but all we're interested in here is the keys. | [reply] [d/l] [select] |
RE: Re: All array elements the same?
by eLore (Hermit) on Aug 01, 2000 at 21:19 UTC
|
Davorg:
Out of curiosity, that *would* count as brute force, wouldn't it? Please explain why, or why not, if you have time.
update:
Would this be considered a tied hash? According to camel pg 182, perl does walk entire tied hash. (brute force) | [reply] |
|
my @Unique;
for (my $i = 0; $i != @Arr; $i++){
my $Val = $Arr[$i];
my $Found = 0;
for (my $j = 0; $j != @Unique; $j++){
if ($Val == $Unique[$j]){
$Found = 1;
last;
}
}
if (not $Found){
push @Unique, $Val;
}
}
print 'Unique values are: ', join ', ', @Unique;
Now, in perl idiom, we do all that in one line using a hash.
Of course, the specific problem we are solving here would
be much simpler, even in 'C' mentality...
I guess my definition of brute-force is "the opposite of
perl idiom."
Russ
Brainbench 'Most Valuable Professional' for Perl | [reply] [d/l] |
|
I would argue that this is still brute-force. Since
every array element (at least till a mismatch is found)
must still be examined. In this case "brute-force" =
O(n) (time is proportional to the size of the list).
The technique presented above has the performance characteristic
that its speed is directly proportional to the list size
so IMHO it is still brute-force (or at least performance-equivalent to brute-force).
However, if you were to do something like populate your list
elements into a hash as keys at the same time as you added them to
a list then determining that they were all the same would be O(1),
better than brute-force. However, this would slow-down your "add an
element to the list" function.
| [reply] |
|
| [reply] |
|
|
|
I suppose it depends what your definition of 'brute
force' is. I'd say that a brute force solution would
involve looping around the array checking each element and
therefore this isn't brute force.
This certainly isn't a tied hash. A tied hash is some
random object whcih you can access via a hash interface.
This is a real hash which just happens to contain some
interesting information about an array.
--
<http://www.dave.org.uk>
European Perl Conference - Sept 22/24 2000, ICA, London
<http://www.yapc.org/Europe/>
| [reply] |
|
Why is recursion always considered the same as "brute force".
I'm pretty sure they aren't always the same.
I've seen some beautiful recursive techniques that were
both elegant and efficient.
J. J. Horner
Linux, Perl, Apache, Stronghold, Unix
jhorner@knoxlug.org http://www.knoxlug.org/
| [reply] |
RE: Re: All array elements the same?
by Nitsuj (Hermit) on Aug 01, 2000 at 23:02 UTC
|
Reverse brute force.
It is sort of brute force in the reverse, rather than checking each element as it comes, you are making an equivalent object and checking it. The means that you are generating it by are not brute force by abstraction, but in actual implementation they might be, which really depends on the algorithm employeed in the operators which you used (I've never read the PERL souce to those operators, so I don't know). Still, it is a very elegant piece of code, and I know that I enjoyed it :-)
"We're all different!"
"I'm not"
-The Life of Brian | [reply] |