Ok, your solutions:
The first one is less than optimal. First, you're starting with $x = 1, which means that after the loop terminates $x will overstate the count by one. Why not start with $x = 0, and then pre-increment instead of post-incrementing $x? In other words, ++$x, instead of $x++. The next issue is the regexp you used. It will match just about anything containing "foo", including "foolish". Is that intentional? Maybe /^foo$/ would be better, or perhaps /\bfoo\b/. And the last thing to mention is the use of print within the loop. You're printing on each iteration, which creates an IO bottleneck, plus a lot of clutter. If $x started at zero, you could print after the loop terminates.
Your second solution goes to a lot of extra work and memory inefficiency by creating $str as a temporary stringified version of @arr. And the other problem is that $& only shows the actual most recent match, not some count of the number of possible times the regular expression could have matched. Don't use a special variable, use this:
my $count = () = $str =~ m/\bfoo\b/g;
But I still feel it's a bad solution because you're creating a temporary string unnecessarily.
The grep solution is probably the best for a one-time count. The hash solution is probably better if you're doing the count several times, but it does have two problems: you're still creating the temporary copy (the hash), and the creation of a hash is a more computationally expensive operation than running through the array one time counting, as is done in the grep method.
One other thing: "utioecia". There you go; the keystrokes you saved by abbreviating "special" and "solution." You can cut and paste them into your future posts so that you can retain clarity without wasting those eight keystrokes. ;)
|