【问题标题】:Count the number of times a character occurs consecutively in a binary string - Perl计算一个字符在二进制字符串中连续出现的次数 - Perl
【发布时间】:2014-03-12 05:38:39
【问题描述】:

我有一个由 1 和破折号组成的二进制 $strings 列表。

1--1-1-111---1--
1--1-11111111-11
1111-11111--1111

我正在从一个 txt 文件中检索它,以计算每个字符串中存在多少连续破折号。例如,在第一个字符串中,存在 3 个连续破折号出现一次,2 个破折号出现两次,单个破折号出现 3 次的一段。在第二个字符串中,我有一段连续的 2 个破折号和两次出现的单个破折号。

我想要的结果是输出或保留在数组或散列中以供进一步操作,连续破折号的出现和此符号中的频率:

3-1, 2-2, 1-3
2-1, 1-2
2-1, 1-1

我正在使用这个语句来计算全局破折号的出现次数:

$dash_freq = (($string =~ tr/-//) + 1);

但是,我想知道正则表达式如何计算连续出现的频率。

【问题讨论】:

  • 我不认为你可以用正则表达式来做到这一点。写个循环就好了。
  • 每个字符串的长度可以有很大的不同。它们的长度不一样。
  • 为什么这是个问题?只需遍历字符串中的所有字符。

标签: regex perl


【解决方案1】:

也许以下内容会有所帮助:

use strict;
use warnings;

while (<DATA>) {
    my ( %hash, @nums );
    $hash{ length $1 }++ while /(-+)/g;
    push @nums, "$_-$hash{$_}" for sort { $b <=> $a } keys %hash;
    print join( ', ', @nums ), "\n";
}

__DATA__
1--1-1-111---1--
1--1-11111111-11
1111-11111--1111

输出:

3-1, 2-2, 1-2
2-1, 1-2
2-1, 1-1

【讨论】:

  • 我正要评论说,OP 的描述似乎暗示单个破折号的计数为 3,但您的解决方案确认这只是一个错字。
  • 谢谢 Kenosis,这很有帮助。
【解决方案2】:

您也可以使用split 提取破折号列表,如下所示:

#!/usr/bin/perl

use warnings;
use strict;

use Data::Dumper;

my @dash_freq;
while (<DATA>) {
    chomp;
    my @dashes = split /1+/;

    my %freq;
    $freq{length($_)}++ foreach grep { m/-/ } @dashes;

    push @dash_freq, \%freq;
}

print Dumper(\@dash_freq);

__DATA__
1--1-1-111---1--
1--1-11111111-11
1111-11111--1111
---1111-11111--1111

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-04
    • 2021-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多