使用 perl 编写一个程序来比较 2 个版本
Write a program to compare 2 versions using perl
下面的程序比较两个版本是否正确?
说 v1 = 3.0.1 和 v2 = 4.5.5
sub VerChecker
{
my $v1 = shift;
my $v2 = shift;
my @v1_parts = split (/./, $v1);
my @v2_parts = split (/./, $v2);
for( my $i = 0; $i < @v1_parts; $i++ )
{
if( $v1_parts[$i] < $v2_parts[$i] )
{
return -1;
}
elsif( $v1_parts[$i] > $v2_parts[$i] )
{
return 1;
}
}
# equal !
return 0;
}
你能更正上面的代码吗
#!/bin/env perl
use strict;
use warnings;
sub ver_checker {
my ($v1, $v2) = @_;
my @v1_parts = split(/\./, $v1);
my @v2_parts = split(/\./, $v2);
my $num_parts = scalar @v1_parts;
if (scalar @v2_parts > $num_parts) {
$num_parts = scalar @v2_parts;
}
for my $part (0 .. $num_parts-1) {
$v1_parts[$part] = sprintf("%04d", $v1_parts[$part] // 0);
$v2_parts[$part] = sprintf("%04d", $v2_parts[$part] // 0);
}
return join('', @v1_parts) cmp join('', @v2_parts);
}
print ver_checker('3.0.1', '4.5.5')."\n";
print ver_checker('3.0', '4.5.5')."\n";
print ver_checker('3.0.1', '4')."\n";
print ver_checker('5', '4')."\n";
有几件事要提一下:
use strict; use warnings;
总是
- Camel Case 不再有趣了。使用 lowercase_and_underscores
- 在正则表达式中转义文字。您的拆分需要避开经期
- 我发现当比较像这样点缀的东西时,填充所有内容并比较字符串更容易。您的代码仅在版本号为三点数字时才考虑。我通过让它选择最长的虚线数字并填充它们来使其更便携(即
3.1
vs 5.0.1
本质上变成 3.1.0
vs 5.0.1
,并填充到 000300010000
vs 000500000001
。cmp
returns 你的 -1/0/1
值。
澄清拆分失败的原因:
您的拆分需要避开这段时间。你在每个角色上分裂,这意味着没有捕获。 运行 这个脚本自己看。
#!/bin/env perl
use strict; use warnings;
use Data::Dumper;
my $foo = 'a.b.c';
my @split1 = split(/./, $foo); # gives []
my @split2 = split(//, $foo); # gives ['a', '.', 'b', '.', 'c']
my @split3 = split(/\./, $foo); # gives [ 'a', 'b', 'c']
print Dumper [ \@split1, \@split2, \@split3 ];
下面的程序比较两个版本是否正确? 说 v1 = 3.0.1 和 v2 = 4.5.5
sub VerChecker
{
my $v1 = shift;
my $v2 = shift;
my @v1_parts = split (/./, $v1);
my @v2_parts = split (/./, $v2);
for( my $i = 0; $i < @v1_parts; $i++ )
{
if( $v1_parts[$i] < $v2_parts[$i] )
{
return -1;
}
elsif( $v1_parts[$i] > $v2_parts[$i] )
{
return 1;
}
}
# equal !
return 0;
}
你能更正上面的代码吗
#!/bin/env perl
use strict;
use warnings;
sub ver_checker {
my ($v1, $v2) = @_;
my @v1_parts = split(/\./, $v1);
my @v2_parts = split(/\./, $v2);
my $num_parts = scalar @v1_parts;
if (scalar @v2_parts > $num_parts) {
$num_parts = scalar @v2_parts;
}
for my $part (0 .. $num_parts-1) {
$v1_parts[$part] = sprintf("%04d", $v1_parts[$part] // 0);
$v2_parts[$part] = sprintf("%04d", $v2_parts[$part] // 0);
}
return join('', @v1_parts) cmp join('', @v2_parts);
}
print ver_checker('3.0.1', '4.5.5')."\n";
print ver_checker('3.0', '4.5.5')."\n";
print ver_checker('3.0.1', '4')."\n";
print ver_checker('5', '4')."\n";
有几件事要提一下:
use strict; use warnings;
总是- Camel Case 不再有趣了。使用 lowercase_and_underscores
- 在正则表达式中转义文字。您的拆分需要避开经期
- 我发现当比较像这样点缀的东西时,填充所有内容并比较字符串更容易。您的代码仅在版本号为三点数字时才考虑。我通过让它选择最长的虚线数字并填充它们来使其更便携(即
3.1
vs5.0.1
本质上变成3.1.0
vs5.0.1
,并填充到000300010000
vs000500000001
。cmp
returns 你的-1/0/1
值。
澄清拆分失败的原因: 您的拆分需要避开这段时间。你在每个角色上分裂,这意味着没有捕获。 运行 这个脚本自己看。
#!/bin/env perl
use strict; use warnings;
use Data::Dumper;
my $foo = 'a.b.c';
my @split1 = split(/./, $foo); # gives []
my @split2 = split(//, $foo); # gives ['a', '.', 'b', '.', 'c']
my @split3 = split(/\./, $foo); # gives [ 'a', 'b', 'c']
print Dumper [ \@split1, \@split2, \@split3 ];