使用Perl按特定字母顺序对字符串排序

使用Perl按特定字母顺序对字符串排序,perl,sorting,cpan,Perl,Sorting,Cpan,我正试图用Perl以特定的字母顺序对名称列表进行排序,以执行一些特殊功能。 排序的方式与排序{$a cmp$b}相同,但字母顺序不同。 例如,使用任意字符顺序进行排序“abdrtwsuiopqe987654”… 我试图处理sort{$a myFunction$b},但我是Perl新手,我不知道如何正确组织myFunction,以获得我想要的 是否有提供此功能的特定功能(包) 您有处理字符串的自定义排序函数的示例吗 您知道如何(或在哪个源文件中)用Perl实现cmp函数来查看它是如何工作的吗 以

我正试图用Perl以特定的字母顺序对名称列表进行排序,以执行一些特殊功能。
排序的方式与
排序{$a cmp$b}
相同,但字母顺序不同。
例如,使用任意字符顺序进行排序“abdrtwsuiopqe987654”…

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

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

    • 以下可能是最快的[1]:

      或者,如果您想要更具活力的东西,以下可能是最快的[2]:

      我们可以一个字符一个字符地比较,但速度要慢得多

    • 从技术上讲,使用GRT可以加快速度

      my @sorted =
         map /\0(.*)/s,
         sort
         map { tr{abdrtwsuiopqe987654}{abcdefghijklmnopqrs}r . "\0" . $_ }
         @unsorted;
      
      my @sorted =
         map /\0(.*)/s,
         sort
         map { ( pack 'C*', map $map[ord($_)], unpack 'C*', $_ ) . "\0" . $_ }
         @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
      
      $perl-MO=简明,-exec-e'$x cmp$y'
      1进入
      2下一状态(主1-e:1)v:{
      3 gvsv[*x]s
      4 gvsv[*y]s
      5 scmp[t3]vK/2
      6离开[1参考]vKP/REFC
      
      scmp
      操作符是由中的
      pp\u scmp
      函数实现的,它实际上只是
      sv\u cmp\u标志
      使用区域设置时的包装;
      无效。
      sv\u cmp\u标志
      使用C库函数或UTF-8感知版本(取决于标量的类型)

      或者在不支持
      tr/../../../r

      my @sorted = keysort { my $key = $_;
                             $key =~ tr/abdrtwsuiopqe987654/abcdefghijklmnopqrs/;
                             $key } @data;
      
      您还可以为此类数据创建一个专门的排序子例程,如下所示:

      use Sort::Key::Maker 'my_special_sort',
                           sub { tr/abdrtwsuiopqe987654/abcdefghijklmnopqrs/r },
                           qw(string);
      
      my @sorted = my_special_sort @data;
      my @sorted2 = my_special_sort @data2;
      

      可能应该缓存这些转写,或者至少记下如果有重复的话会发生的重复计算。@Hunter McMillen,我认为收益不会太大,但我添加了GRT解决方案。逐字符比较正是我想要的。回答不错!为什么?可能慢100倍!
      $ 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
      
      use Sort::Key qw(keysort);
      my @sorted = keysort { tr/abdrtwsuiopqe987654/abcdefghijklmnopqrs/r } @data;
      
      my @sorted = keysort { my $key = $_;
                             $key =~ tr/abdrtwsuiopqe987654/abcdefghijklmnopqrs/;
                             $key } @data;
      
      use Sort::Key::Maker 'my_special_sort',
                           sub { tr/abdrtwsuiopqe987654/abcdefghijklmnopqrs/r },
                           qw(string);
      
      my @sorted = my_special_sort @data;
      my @sorted2 = my_special_sort @data2;