Ich hatte das Gefühl, dass es eine bessere Möglichkeit geben muss, das Auftreten zu zählen, als ein Sub in Perl, Shell unter Linux zu schreiben.

#/usr/bin/perl -w
use strict;
return 1 unless $0 eq __FILE__;
main() if $0 eq __FILE__;
sub main{
    my $str = "ru8xysyyyyyyysss6s5s";
    my $char = "y";
    my $count = count_occurrence($str, $char);
    print "count<$count> of <$char> in <$str>\n";
}
sub count_occurrence{
    my ($str, $char) = @_;
    my $len = length($str);
    $str =~ s/$char//g;
    my $len_new = length($str);
    my $count = $len - $len_new;
    return $count;
}
10
Gang 23 Dez. 2015 im 16:56

4 Antworten

Beste Antwort

Das Zählen der Vorkommen eines Zeichens in einer Zeichenfolge kann mit einer Zeile in Perl durchgeführt werden (im Vergleich zu Ihren 4 Zeilen). Es ist kein Sub erforderlich (obwohl die Kapselung der Funktionalität in einem Sub nichts auszusetzen hat). Von perlfaq4 "Wie kann ich die Anzahl der Vorkommen eines Teilstrings innerhalb eines Strings zählen?"

use warnings;
use strict;

my $str = "ru8xysyyyyyyysss6s5s";
my $char = "y";
my $count = () = $str =~ /\Q$char/g;
print "count<$count> of <$char> in <$str>\n";
14
ikegami 23 Dez. 2015 im 19:18

Wenn das Zeichen konstant ist, ist Folgendes am besten:

my $count = $str =~ tr/y//;

Wenn das Zeichen variabel ist, würde ich Folgendes verwenden:

my $count = length( $str =~ s/[^\Q$char\E]//rg );

Ich würde nur Folgendes verwenden, wenn ich Kompatibilität mit Perl-Versionen älter als 5.14 haben möchte (da es langsamer ist und mehr Speicher benötigt):

my $count = () = $str =~ /\Q$char/g;

Das Folgende verwendet keinen Speicher, ist jedoch möglicherweise etwas langsam:

my $count = 0;
++$count while $str =~ /\Q$char/g;
9
ThisSuitIsBlackNot 23 Dez. 2015 im 22:09

In einem schönen * Bash / Coreutils / Grep Einzeiler:

$ str=ru8xysyyyyyyysss6s5s
$ char=y
$ fold -w 1 <<< "$str" | grep -c "$char"
8

Oder vielleicht

$ grep -o "$char" <<< "$str" | wc -l
8

Der erste funktioniert nur, wenn der Teilstring nur ein Zeichen lang ist. Die zweite Funktion funktioniert nur, wenn sich die Teilzeichenfolgen nicht überlappen.

* Nicht wirklich.

4
Benjamin W. 23 Dez. 2015 im 15:17

toolic hat eine korrekte Antwort gegeben, aber Sie sollten Ihre Werte möglicherweise nicht fest codieren, um das Programm wiederverwendbar zu machen.

use strict;
use warnings;

die "Usage: $0 <text> <characters>" if @ARGV < 1;
my $search = shift;                    # the string you are looking for
my $str;                               # the input string
if (@ARGV && -e $ARGV[0] || !@ARGV) {  # if str is file, or there is no str
    local $/;                          # slurp input
    $str = <>;                         # use diamond operator
} else {                               # else just use the string
    $str = shift;
}
my $count = () = $str =~ /\Q$search\E/gms;
print "Found $count of '$search' in '$str'\n";

Auf diese Weise können Sie das Programm verwenden, um das Auftreten eines Zeichens oder einer Zeichenfolge in einer Zeichenfolge, einer Datei oder einer Standardeingabe zu zählen. Zum Beispiel:

count.pl needles haystack.txt
some_process | count.pl foo
count.pl x xyzzy
2
Community 23 Mai 2017 im 12:04