1

部品番号、つまり英数字の文字列を処理する必要があります。部品番号は 14 文字ですが、部品構造 (sc 上位コンポーネント) の番号は短くなります。メタデータ変換では、上位レベルのパーツ番号を、末尾のゼロを付けて 14 文字の完全な長さに拡張する必要があります。

私は次の解決策を思いついた

my $number = "M30SA0000002"; # same upper level part number
my $len = 14;

if (length($number) < $len) {
  print "Number [$number] is smaller, length (" . length ($number) . ")\n";
  $number = sprintf("%-${len}s", $number);
  $number =~ tr/ /0/;
}
print "\New number [$number], length (" . length ($number) . ")\n"

ここに出力があります

Number [M30SA0000002] is smaller, length (12)
New number [M30SA000000200], length (14)

これにより望ましい結果が得られますが、この単純なタスクを 2 行で実行するのは少し厄介です。1行でそれを行う方法はありますか?sprintf末尾の文字で文字列を展開する方法を提供しないのは残念です。

運用環境は、Windows Server マシン、Perl バージョン5.14.2.1、CPAN モジュールなし、利用可能なコア モジュールのみで実行されます。

編集:4つのソリューションをベンチマークしました

use Benchmark qw(:all);
timethese(10000000, {
            'While' => sub { my $number = "M30SA0000002"; $number .= '0' while 14 > length $number; },
            'Repeat' => sub { my $number = "M30SA0000002"; $number .= '0' x (14 - length $number); },
            'Substring' => sub { my $number = "M30SA0000002"; $number = substr($number . "0" x 14, 0, 14); },
            'Sprintf' => sub { my $number = "M30SA0000002"; $number = sprintf("%-14s", $number); $number =~ tr/ /0/; },
});

結果は次のとおりです。

Benchmark: timing 10000000 iterations of Repeat, Sprintf, Substring, While...
    Repeat:  2 wallclock secs ( 1.65 usr +  0.00 sys =  1.65 CPU) @ 6045949.21/s (n=10000000)
   Sprintf:  3 wallclock secs ( 3.90 usr +  0.00 sys =  3.90 CPU) @ 2564102.56/s (n=10000000)
 Substring:  3 wallclock secs ( 2.78 usr +  0.00 sys =  2.78 CPU) @ 3602305.48/s (n=10000000)
     While:  2 wallclock secs ( 2.81 usr +  0.00 sys =  2.81 CPU) @ 3561253.56/s (n=10000000)

反復ソリューションは、それらすべての中で最速のようです。

4

2 に答える 2

3

while修飾子を「追加」割り当てと一緒に使用できます。

$number .= '0' while 14 > length $number;

または、いくつかの計算を行い、繰り返し演算子を使用します (@ loldopに感謝):

$number .= '0' x (14 - length $number);
于 2013-08-05T14:04:43.237 に答える