【发布时间】:2009-09-22 13:40:58
【问题描述】:
我正在尝试在 Perl 中编写合并排序算法,并尝试复制 pseudo code from Wikipedia。
这就是我所拥有的:
sub sort_by_date {
my $self = shift;
my $collection = shift;
print STDERR "\$collection = ";
print STDERR Dumper $collection;
if ( @$collection <= 1 ) {
return $collection;
}
my ( $left, $right, $result );
my $middle = ( @$collection / 2 ) - 1;
my $x = 0;
for ( $x; $x <= $middle; $x++ ) {
push( @$left,$collection->[$x] );
}
$x = $middle + 1;
for ( $x; $x < @$collection; $x++ ) {
push( @$right,$collection->[$x] );
}
$left = $self->sort_by_date( $left );
$right = $self->sort_by_date( $right );
print STDERR '$left = ';
print STDERR Dumper $left;
print STDERR '$right = ';
print STDERR Dumper $right;
print STDERR '$self->{\'files\'}{$left->[@$left-1]} = ';
print STDERR Dumper $self->{'files'}{$left->[@$left-1]};
print STDERR '$self->{\'files\'}{$right->[0]} = ';
print STDERR Dumper $self->{'files'}{$right->[0]};
if ( $self->{'files'}{$left->[@$left-1]}{'modified'} > $self->{'files'}{$right->[0]}{'modified'} ) {
$result = $self->merge_sort( $left,$right );
}
else {
$result = [ @$left, @$right ];
}
return $result;
}
## We're merge sorting two lists together
sub merge_sort {
my $self = shift;
my $left = shift;
my $right = shift;
my @result;
while ( @$left > 0 && @$right > 0 ) {
if ( $self->{'files'}{$left->[0]}{'modified'} <= $self->{'files'}{$right->[0]}{'modified'} ) {
push( @result,$left->[0] );
shift( @$left );
}
else {
push( @result,$right->[0] );
shift( @$right );
}
}
print STDERR "\@$left = @$left\n";
print STDERR "\@$right = @$right\n";
if ( @$left > 0 ) {
push( @result,@$left );
}
else {
push( @result,@$right );
}
print STDERR "\@result = @result\n";
return @result;
}
我得到的错误 + 我的调试打印语句的输出如下:
$collection = $VAR1 = [
'dev/css/test.css',
'dev/scripts/out.tmp',
'dev/scripts/taxonomy.csv',
'dev/scripts/wiki.cgi',
'dev/scripts/wiki.cgi.back',
'dev/templates/convert-wiki.tpl',
'dev/templates/includes/._menu.tpl',
'dev/templates/test.tpl'
];
$collection = $VAR1 = [
'dev/css/test.css',
'dev/scripts/out.tmp',
'dev/scripts/taxonomy.csv',
'dev/scripts/wiki.cgi'
];
$collection = $VAR1 = [
'dev/css/test.css',
'dev/scripts/out.tmp'
];
$collection = $VAR1 = [
'dev/css/test.css'
];
$collection = $VAR1 = [
'dev/scripts/out.tmp'
];
$left = $VAR1 = [
'dev/css/test.css'
];
$right = $VAR1 = [
'dev/scripts/out.tmp'
];
$self->{'files'}{$left->[@$left-1]} = $VAR1 = {
'type' => 'file',
'modified' => '0.764699074074074'
};
$self->{'files'}{$right->[0]} = $VAR1 = {
'type' => 'file',
'modified' => '340.851956018519'
};
$collection = $VAR1 = [
'dev/scripts/taxonomy.csv',
'dev/scripts/wiki.cgi'
];
$collection = $VAR1 = [
'dev/scripts/taxonomy.csv'
];
$collection = $VAR1 = [
'dev/scripts/wiki.cgi'
];
$left = $VAR1 = [
'dev/scripts/taxonomy.csv'
];
$right = $VAR1 = [
'dev/scripts/wiki.cgi'
];
$self->{'files'}{$left->[@$left-1]} = $VAR1 = {
'type' => 'file',
'modified' => '255.836377314815'
};
$self->{'files'}{$right->[0]} = $VAR1 = {
'type' => 'file',
'modified' => '248.799166666667'
};
@ARRAY(0x8226b2c) = dev/scripts/taxonomy.csv
@ARRAY(0x8f95178) =
@result = dev/scripts/wiki.cgi dev/scripts/taxonomy.csv
$left = $VAR1 = [
'dev/css/test.css',
'dev/scripts/out.tmp'
];
$right = $VAR1 = 2;
$self->{'files'}{$left->[@$left-1]} = $VAR1 = {
'type' => 'file',
'modified' => '340.851956018519'
};
$self->{'files'}{$right->[0]} = [Tue Sep 22 13:47:19 2009] [error] [Tue Sep 22 13:47:19 2009] null: Can't use string ("2") as an ARRAY ref while "strict refs" in use at ../lib/Master/ProductVersion.pm line 690.\n
现在您在代码中看到的额外复杂性是,对于传入的 $collection array_ref 中的每个项目,还有一个包含 item => { type => 'file', modified => 'date 的项目的哈希条目-last-modified' } 并且我正在尝试对每个文件的最后修改日期进行排序。
我的大脑基本上无法应对递归,而且我无法弄清楚我哪里出错了 - 这可能很明显和/或非常错误。任何帮助将不胜感激......或者我正在重写为插入排序!
谢谢
【问题讨论】:
-
提供您正在使用的数据可能会有所帮助。
-
一些问题:(1)为什么这种排序采用
$self? (2) 数据到底是如何构建到结构中的? (3) 为什么您的函数不更接近于“要排序的数组中的每个项目都具有与之关联的所有所需信息”?戳“$self”以查找正在排序的集合中项目的时间属性……有点奇怪。
标签: perl algorithm sorting mergesort