I have a string similar to: but much longer
my $a = "000000001111111111000000011111111111111111111111111111111";
I am counting the number of "1"'s with:
my $total_1_available = $a =~ tr/1//;
And that works amazingly well and is really FAST.
HOWEVER, I also wish to count (in a fast way), the total number of consecutive 1's in a row. The MAX COUNT of "1's" consecutively.
IN the example above, it would return the count of:
11111111111111111111111111111111
As this is the maximum in a row.
So, I end up with the TOTAL_COUNT and also the TOTAL_CONSECUTIVE_COUNT.
I have it working with a REGEXP which basically replaces the 1's and then counts what was replaced and loops around...which actually is totally fine and works... but it doesn't "feel" right.
Ideally I don't want to replace the string at all as I am looking for the max consecutive count.
But, I know in Perl this probably isn't the fastest or cleanest way.
Could you teach me a better way please and increase my learning?
AS requested this is my current code:
my $a= "0110011001101111";
my $total_1_available = $a =~ tr/1//;
print "Total number of 1's = $total_1_available\n";
my $max_c = 0;
while ( $a=~s/(1+)/ / ) {
$max_c = length($1) if length($1) > $max_c;
}
print "Consecutive count = $max_c\n";
And FINAL CODE:
use strict;
use warnings;
use Benchmark ':all';
use String::Random;
## We test 525,600 as this is the length of the string.
## Actually each 0 or 1 represents a minute of the year.
## And these represent engineer minues available in a 24 hr / 365 day year.
## And there are lots and lots of engineers.
## Hence my wish to improve the performance and I wish to thank everyone whom responded.
## there are a lot more 0's than 1's so hack to sort of simulate
my $test_regex = '[0][0][0][0][0][0-1][0-1][0-1][0-1][0-1]' x 52560;
my $pass = String::Random->new;
my $string = $pass->randregex($test_regex);
cmpthese(-1, {
org => sub { my $max = 0; while ($string =~ /(1+)/g) { my $len = length($1); if ($max < $len) { $max = $len } } },
hack => sub { my $match = ""; while ($string =~ /(${match}1+)/g) { $match = $1; } length $match }
});
# BLOWN AWAY !!!!!!
# BLOWN AWAY !!!!!!
# BLOWN AWAY !!!!!!
# BLOWN AWAY !!!!!!