len8200
len8200

Reputation: 85

How to count the number of zeros in a string?

How to count the number of zeros in a string of this type:

my $string =  '11100000000010000011000';

Upvotes: 1

Views: 260

Answers (3)

petrch
petrch

Reputation: 1968

Edit: TLDR: The following are two most common and efficient solutions (mentioned also by other answers). For appreciation of how they work read the rest of the answer.

my $count = $string =~ tr/0//;     # solution 1
my $count = () = $string =~ /0/g;  # solution 2 

The long story

So my first naive solution was this:

my $string =  '11100000000010000011000';
my @ar = split //,$string;
@b = grep { $_ == 0 } @ar;
print scalar @b,"\n";

While it works, it is not really a "perl-style" solution. So I looked around and found this article: https://www.effectiveperlprogramming.com/2010/12/count-the-number-of-things-in-a-string/ which shows how to count the number of zeroes and ones at the same time.

Based on that I created the following:

my $string =  '11100000000010000011000';
my $count = () = $string =~ /0/g;
print "count: ",$count,"\n";

The most intriguing are probably the empty parentheses. They are explained in this interesting article about perl idioms: https://www.perlmonks.org/?node_id=527973

Perl expression results may depend on their "context", so by using something as a scalar or as an array I tell perl what I expect to get. () "forces array context". Without it I would expect a scalar, which would get me true/false result of that match.

Once we have an array we force scalar context by assigning the array to a scalar variable and it then returns its length.

Edit: Other solutions suggested using tr/// in the same fashion. It seems that it is maybe even more popular and it may be faster in some situations (it has to modify the string though). But the principle of the "list context" stays the same. https://perldoc.perl.org/perlop#Regexp-Quote-Like-Operators search for "list context" on that page if you want to learn more about it. It applies to most operators. But their behavior may differ.

Upvotes: 4

Ashish Kumar
Ashish Kumar

Reputation: 851

Whenever it comes to counting items in Perl, I have learned, seen and used Hashes, something like this would help:

use strict;
use warnings;

# your string
my $string = '11100000000010000011000';

# has to store the item counts
my %count;

# split: read the string character by character
for my $z (split //, $string) {
    # add to the count
    $count{$z}++;
}

# read the keys of hash count
#  and sort the output
for my $k (sort {$a <=> $b} keys %count) {
    # display the counts
    print "$k has $count{$k} occurrences\n";
}

Results:

[user@localhost ~]$ perl zero.pl 
0 has 17 occurrences
1 has 6 occurrences

Upvotes: 2

choroba
choroba

Reputation: 241808

The traditional and fast way is to use tr:

my $count = $string =~ tr/0//;

Upvotes: 7

Related Questions