加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

使用Perl对具有特定字母顺序的字符串进行排序

发布时间:2020-12-15 22:05:48 所属栏目:大数据 来源:网络整理
导读:我正在尝试使用Perl对具有特定字母顺序的名称列表进行排序,以执行一些特殊功能. 排序的工作方式与排序{$a cmp $b}相同,但使用不同的字母序列. 例如,使用任意字符顺序“abdrtwsuiopqe987654”进行排序…… 我尝试处理sort {$a myFunction $b},但我是Perl的新
我正在尝试使用Perl对具有特定字母顺序的名称列表进行排序,以执行一些特殊功能.
排序的工作方式与排序{$a cmp $b}相同,但使用不同的字母序列.
例如,使用任意字符顺序“abdrtwsuiopqe987654”进行排序……

我尝试处理sort {$a myFunction $b},但我是Perl的新手,我不知道如何正确组织myFunction以获得我想要的东西.

>是否有提供此功能的特定功能(包)?
>你有一个处理字符串的自定义排序函数的例子吗?
>你知道如何(或在哪个源文件中)使用Perl实现的cmp函数来查看它是如何工作的?

解决方法

以下可能是最快的[1]:
sub my_compare($$) {
    $_[0] =~ tr{abdrtwsuiopqe987654}{abcdefghijklmnopqrs}r
       cmp
    $_[1] =~ tr{abdrtwsuiopqe987654}{abcdefghijklmnopqrs}r
}

my @sorted = sort my_compare @unsorted;

或者如果你想要更动态的东西,以下可能是最快的[2]:

my @syms = split //,'abdrtwsuiopqe987654';
my @map; $map[ord($syms[$_])] = $_ for 0..$#syms;

sub my_compare($$) {
    (pack 'C*',map $map[ord($_)],unpack 'C*',$_[0])
       cmp
    (pack 'C*',$_[1])
}

my @sorted = sort my_compare @unsorted;

我们可以逐字逐句地比较,但这会慢得多.

use List::Util qw( min );

my @syms = split //,'abdrtwsuiopqe987654';
my @map; $map[ord($syms[$_])] = $_ for 0..$#syms;

sub my_compare($$) {
    my $l0 = length($_[0]);
    my $l1 = length($_[1]);
    for (0..min($l0,$l1)) {
       my $ch0 = $map[ord(substr($_[0],$_,1))];
       my $ch1 = $map[ord(substr($_[1],1))];
       return -1 if $ch0 < $ch1;
       return +1 if $ch0 > $ch1;
    }

    return -1 if $l0 < $l1;
    return +1 if $l0 > $l1;
    return 0;
}

my @sorted = sort my_compare @unsorted;

>从技术上讲,使用GRT可以更快地完成.

my @sorted =
   map /(.*)/s,sort
   map { tr{abdrtwsuiopqe987654}{abcdefghijklmnopqrs}r . "" . $_ }
   @unsorted;

>从技术上讲,sort map { ( pack 'C*',$_ ) . "" . $_ } @unsorted;

cmp由scmp运算符实现.

$perl -MO=Concise,-exec -e'$x cmp $y'
1  <0> enter
2  <;> nextstate(main 1 -e:1) v:{
3  <#> gvsv[*x] s
4  <#> gvsv[*y] s
5  <2> scmp[t3] vK/2
6  <@> leave[1 ref] vKP/REFC

scmp操作符由pp.c中的pp_scmp函数实现,当使用locale时,它实际上只是sv.c中sv_cmp_flags的包装器;没有效果. sv_cmp_flags使用C库函数memcmp或UTF-8识别版本(取决于标量的类型).

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读