使用重复字符计数实现一个执行字符串压缩的方法。例如,aabcccccaaaaaaa将成为a2b1c5a7。将字符串解压缩为原始字符串。
我尝试了下面的代码但是正在寻找一些衬里正则表达式解决方案 -
sub print_word{
my $s=shift;
my @a=split(//, $s);
my $c=1;
my $r='';
my $t=$a[0];
for( my $i=1; $i<=$#a; $i++) {
if($t eq $a[$i]) {
$c++;
}else{
$r.=$t."$c";
$t=$a[$i];
$c=1;
}
}
$r.=$t."$c";
return $r;
}
print print_word('aabcccccaaaaaaa') . "\n";
请在一行中使用正则表达式提供一些内容。
答案 0 :(得分:6)
好的,这里的诀窍是 - 将引用与字符串匹配;
my $string = 'aabcccccaaaaaaa';
$string =~ s/((\w)\2*)/ "$2". length ($1) /eg;
print $string;
这给出了:
a2b1c5a7
我们捕获&#39;一个单词字符(\w
),我们使用\2*
来表示零或更多(因此,由于第一个字母而使其更多一个&#39;)。
然后我们将 封装在另一个捕获组中,这意味着我们将\2
或$2
作为我们的单个字母,\1
或{{1作为同一个字母的子字符串。
我们打印$1
然后 - 因为我们在正则表达式上设置了$2
标志 - 它评估e
并插入它。
为了扩展我所说的效率 - 我们需要转到代码分析器。
使用length ( $1 )
:
Devel::NYTProf
您编写的代码:
我的例子
现在,这里有比例问题 - 我的意思是,如果你反复运行,你可能会发现正则表达式解决方案开始了#34; win&#34;。根本没有使用正则表达式的开销,某些正则表达式可能非常昂贵&#39;。例如,请参阅:http://blog.codinghorror.com/regex-performance/
尝试相同的测试 - 例如 - 在循环中运行100,000次,数字开始均匀。
矿:
此致:
但是我仍然建议 - 在您确定需要之前不要担心性能问题。在那之前,请阅读最容易阅读和理解的内容。
我不确定直到我针对另一个问题运行结果catastrophic backtracking,这就是为什么要注意正则表达式&#39;在我心中很高兴。
他们看起来很整洁,他们很聪明,但有时他们有点太聪明。但在这种情况下,这似乎并不适用。正则表达式引擎有一个开销,但一旦它开始工作&#39;而且跑得很好。
找出“聪明”的有用技巧之一。正则表达式是perl -d:NYTProf script.pl
nytprofhtml --open
以我的例子,这打印:
use re 'debug';
你可以看到,在这个例子中,它实际上做了很多工作。但是因为它不需要在任何时候回溯以匹配你的字符串,所以它并不真正浪费任何努力。
答案 1 :(得分:2)
如果您使用/e
修饰符替换表达式,这相当简单。这允许您将Perl表达式放在s///
运算符的替换部分而不是简单的字符串
这是一个演示
use strict;
use warnings;
use 5.010;
my $s = 'aabcccccaaaaaaa';
say $s;
(my $encoded = $s) =~ s/(([a-z])\g2*)/$2.length $1/egi;
say $encoded;
(my $decoded = $encoded) =~ s/([a-z])(\d+)/$1 x $2/egi;
say $decoded;
say $s eq $decoded ? 'Match okay' : 'Round trip failed';
aabcccccaaaaaaa
a2b1c5a7
aabcccccaaaaaaa
Match okay