配列

さて、行数や文字数では簡単すぎてつまらないので、今度は単語数を数えることにしよう。 ここでいう「単語」とは、スペースで区切られた英語風の1単語ということにしておく。 どのようにして数えればよいだろうか。 C 言語ならばいろいろと頭をひねるところだろうが、Perl には Perl なりのやり方がある。 それは split を使う方法だ。

split は、対象となる文字列を、与えられた「区切り文字」を使って分解してくれる関数だ。 たとえば「abc,stu,xyz」という文字列があったとき、コンマを区切りとして「abc」「stu」「xyz」に分解することができるのだ。 書式は次の通り。

split(区切りのパターン, 対象文字列)

split は分解した各文字列を配列にして返してくれる。 配列とは、変数に添字を付けてインデックス化したものだ。 短いサンプルを見せよう。

$s = 'abc,stu,xyz';
@t = split(',', $s);
foreach $i (0 .. $#t) {
	print "$t[$i]\n";
}

split を使っている行にある「@t」というのが配列への代入を表わしている。 配列の個々の要素へは、スカラー変数のように「$」を頭に付けて「$t[2]」のように記述するが、配列そのものは「@」を付けてスカラー変数と区別する。 配列として「@」を付けてアクセスすれば、その配列の要素が何個であろうと、一発で代入やコピーを行うことができる。

配列の要素がいくつあるのかは、特殊な書式「$#」を使って求められる。 正確には「$#t」によって求められるのは、配列の最後の要素の添字の値だ。 Perl では、配列の添字は 0 から始まる(C 言語と同じだが、awk とは異なる)。 だから for を使ってループを作るならこのようになる。

$s = 'abc,stu,xyz';
@t = split(',', $s);
for ($i = 0; $i <= $#t; $i++) {
	print "$t[$i]\n";
}

ついでといっては何だが、foreach はただ数字の列を扱うだけではなく、配列要素を個々に分解して順次ループさせる機能もある。 だからこのコードはこんな風にも書ける。

$s = 'abc,stu,xyz';
@t = split(',', $s);
foreach $i (@t) {
	print "$i\n";
}

ちょっと走りすぎだが、がんばって読み取ってほしい。

さて、最初の問題に話を戻そう。 単語の数を数えたいのであった。 単語の定義はスペースで区切られたものということだったから、読み取った行から単語数を数えるには、split でスペースを区切りとして分解し、その結果何個になったかを数えればよいことになる。 それをコードにしてみよう。

while (<>) {
	@t = split(' ');
	$n += $#t + 1;
}
print $n;

split は、対象文字列を省略すると $_ を分解してくれる。 例の「決まりきったことは省略できる」の応用だ。 「$n += $#t + 1;」は、きちんと書くと「$n = $n + $#t + 1;」という意味になる。 なぜ1を足しているかというと、$#t は配列の要素数には1つ足りないからだ。


[go to next chapter]
[back to index]