使用Perl对值的子数组进行排序
我有以下阵列模式: 2个字母x数字2个字母y数字2个字母z数字等 我想对字母之间的数字进行排序,并保持字母的原样 例如:使用Perl对值的子数组进行排序,perl,sorting,Perl,Sorting,我有以下阵列模式: 2个字母x数字2个字母y数字2个字母z数字等 我想对字母之间的数字进行排序,并保持字母的原样 例如: a b 3 5 7 4 d c 6 3 2 将成为 a b 3 4 5 7 c d 2 3 6 如何在Perl中实现这一点 我试图用什么来保存这些字母的索引 my %index=(); my $count =0 ; foreach (@arr ) { if($_~=/[a-zA-Z]) { $index{$_}=$count; } $count++ }
a b 3 5 7 4 d c 6 3 2
将成为
a b 3 4 5 7 c d 2 3 6
如何在Perl中实现这一点
我试图用什么来保存这些字母的索引
my %index=();
my $count =0 ;
foreach (@arr ) {
if($_~=/[a-zA-Z]) {
$index{$_}=$count;
}
$count++
}
然后尝试用拼接替换这些部分
我还尝试了以下似乎有效的方法:
my @a =qw(a b 1 3 5 3 c d 4 5 2);
my (@b,@c) =();
my $count=0;
foreach (@a) {
if($_=~/[A-Za-z]/){
push @b,sort @c;
push @b,$_;
if($count%2==0) {
@c=();
}
$count++;
}
else {
push @c,$_;
}
}
我想知道是否有一种更有效、更完美的方法来实现这一点?一种方法是循环数组一次,将遇到的第一个数字的索引保持在一个序列中。当遇到字符(表示数字序列已结束)时,请直接在该数组切片中对数字序列进行排序
use strict;
my @arr = ('a','b',3,5,7,4,'d','c',6,3,2);
my $first = -1;
for (my $i = 0; $i < @arr; $i++) {
if($arr[$i] =~ m/[a-z]/i) {
next if ($first == -1);
@arr[$first..($i-1)] = sort {$a<=>$b} @arr[$first..($i-1)];
$first = -1;
} elsif ($first == -1) {
$first = $i;
}
}
#one last time after the loop
@arr[$first..(@arr-1)] = sort {$a<=>$b} @arr[$first..(@arr-1)] if ($first != -1);
print join(',',@arr)."\n";
使用严格;
my@arr=('a','b',3,5,7,4,'d','c',6,3,2);
我的$first=-1;
对于(我的$i=0;$i<@arr;$i++){
如果($arr[$i]=~m/[a-z]/i){
下一个if($first==-1);
@arr[$first..($i-1)]=排序{$a$b}@arr[$first..($i-1)];
$first=-1;
}elsif($first==-1){
$first=$i;
}
}
#循环后的最后一次
@arr[$first..(@arr-1)]=排序{$a$b}@arr[$first..(@arr-1)]如果($first!=-1);
打印联接(“,”,@arr)。“\n”;
这更令人满意吗
#!/usr/bin/env perl
use strict;
use warnings;
my @list = ('a', 'b', '3', '5', '7', '4', 'd', 'c', '6', '3', '2');
for (my $i = 0; $i < scalar(@list); $i++)
{
if ($list[$i] =~ m/[[:alpha:]]/)
{
# Assume $list[$i+1] exists and is alphabetic too!
@list[$i..$i+1] = sort @list[$i..$i+1];
$i++;
}
}
print "@list\n";
我对排序行中的重复切片并不完全满意,但我不确定在使用sort
时是否有办法避免这种情况
当然,因为它是Perl,所以有不止一种方法(TMTOWTDI),所以这两种方法也都能得到正确的答案。我不确定哪一个不那么怪异。我可能缺少一些交换两个变量的惯用方法
#!/usr/bin/env perl
use strict;
use warnings;
my @list = ('a', 'b', '3', '5', '7', '4', 'd', 'c', '6', '3', '2');
for (my $i = 0; $i < scalar(@list); $i++)
{
if ($list[$i] =~ m/[[:alpha:]]/)
{
($list[$i], $list[$i+1]) = ($list[$i+1], $list[$i]) if ($list[$i] gt $list[$i+1]);
$i++;
}
}
print "@list\n";
#/usr/bin/env perl
严格使用;
使用警告;
我的@list=('a','b','3','5','7','4','d','c','6','3','2');
对于(我的$i=0;$i<标量(@list);$i++)
{
如果($list[$i]=~m/[:alpha:][]/)
{
($list[$i],$list[$i+1])=($list[$i+1],$list[$i])如果($list[$i]gt$list[$i+1]);
$i++;
}
}
打印“@list\n”;
交换行是可怕的,因为有三个对列表元素的引用
#!/usr/bin/env perl
use strict;
use warnings;
my @list = ('a', 'b', '3', '5', '7', '4', 'd', 'c', '6', '3', '2');
for (my $i = 0; $i < scalar(@list); $i++)
{
if ($list[$i] =~ m/[[:alpha:]]/)
{
my($x,$y) = (\$list[$i], \$list[$i+1]);
($$x, $$y) = ($$y, $$x) if ($$x gt $$y);
$i++;
}
}
print "@list\n";
#/usr/bin/env perl
严格使用;
使用警告;
我的@list=('a','b','3','5','7','4','d','c','6','3','2');
对于(我的$i=0;$i<标量(@list);$i++)
{
如果($list[$i]=~m/[:alpha:][]/)
{
我的($x,$y)=(\$list[$i],\$list[$i+1]);
($$x,$$y)=($$y,$$x)如果($$x gt$$y);
$i++;
}
}
打印“@list\n”;
交换行是可怕的,因为它显式地交换显式引用。所以不是一个为我编写代码的站点。你必须自己尝试,当你被困在某个地方时,在这里陈述你的问题,然后你会得到帮助。以上是我尝试过的如果你在第二个版本中追求速度,我敢肯定你让它变慢了。比较这两个,
($list[$i],$list[$i+1])=排序($list[$i],$list[$i+1])
和my$r=sub{\\\}->($list[$i],$list[$i+1])@$r=排序@$r代码>。我赌的是简单的那种。
#!/usr/bin/env perl
use strict;
use warnings;
my @list = ('a', 'b', '3', '5', '7', '4', 'd', 'c', '6', '3', '2');
for (my $i = 0; $i < scalar(@list); $i++)
{
if ($list[$i] =~ m/[[:alpha:]]/)
{
my($x,$y) = (\$list[$i], \$list[$i+1]);
($$x, $$y) = ($$y, $$x) if ($$x gt $$y);
$i++;
}
}
print "@list\n";