0 Comments
 いつも拝見しているCTE社さんの開発ブログ「こざくラボ」にて、

索引の連続ノンブルをまとめる

 というネタがあったので自分でもPerlを書いてみた。ちなみにさらなる元ネタはせうぞー先生のこちらのエントリー。

[ruby]索引の連続ノンブルをまとめる

 実は私、Rubyはまったく触った事がないのでわからない。。。とりあえずCTE社さんのブログには「もっといい方法があったら教えてください」とあったのでもっといい方法という訳ではないですが私なりの書き方で書いてみました。ぶっちゃけ、データの操作方法というかやってることは全く一緒ですw まあデータの処理ロジック自体はこの方法がシンプルでよいんではないでしょうか?

 もとネタのエントリを見て頂ければ問題の内容はわかるのですが簡単にいいますと、

1,2,3,5,7,8,9,10

 なんていう文字の並びがあったさいに「3つ以上連続する数字がある場合はハイフンでまとめる」というもの。上記の例であれば結果としては、

1-3,5,7-10

 という感じになる。てことで以下がソース。

#!/usr/bin/perl
use strict;
use utf8;

binmode STDOUT, ":utf8";  #-画面に出力したい文字コード
binmode STDERR, ":utf8";  #-エラー出力に使いたい文字コード
binmode STDIN, ":utf8";  #-標準入力から入ってくる文字コード

sub JoinNumbers {
	#そもそも配列のサイズが2以下ならカンマで繋げて返す
	return join(',', @_) if (@_ <= 2);

	my @No = @_;
	my @JoinNo =();
	my $count = 0;

	# 最初の値をまずはセットしておく
	push(@{$JoinNo[$count]},shift(@No));

	# 数値を調べながらJoinNoに無名配列を格納
	for (@No) {
		$count++ if (abs($_ - $JoinNo[$count][-1]) != 1);
		push(@{$JoinNo[$count]},$_);
	}

	# 格納した無名配列のサイズを調べて3以上ならハイフン、2以下ならカンマで結合
	for (@JoinNo) {
		$_ = @{$_} > 2 ? $_ = $$_[0] . '-' . $$_[-1] : join(',',@{$_});
	}

	# 最後にカンマで結合して返す
	return join(',',@JoinNo);
}

print JoinNumbers(1,2,4,5,8,9,10,12,15,16,17,18,19,20,22) . "\n";
print JoinNumbers(1) . "\n";
print JoinNumbers(100,101,102) . "\n";
print JoinNumbers(1,2,3,5,7,8) . "\n";
print JoinNumbers(55) . "\n";
print JoinNumbers(5,45,46,47,48,56) . "\n";
print JoinNumbers(23) . "\n";
print JoinNumbers(100,23,5) . "\n";
print JoinNumbers(65,64,63,62,60,48,47,46,45,44,43,42,10,8) . "\n";
exit;

 実行結果はこちら、

1,2,4,5,8-10,12,15-20,22
1
100-102
1-3,5,7,8
55
5,45-48,56
23
100,23,5
65-62,60,48-42,10,8


 うーん、元エントリのソースと違うところをあえて挙げるとすれば、

①数値の判定ループに入る前に先頭の値をセット
 こうすることでメインループで無駄なif文を実行せずにすみます。何万件も処理するような場合は多少早くなるかも。

②数値が連続しているかどうかをabs関数にて絶対値チェック
 逆ノン処理にとりあえず対応してみた

 くらいですかね。いやー、やってみたらなかなか面白かったです。三項演算子、はじめてちゃんと使った気がするw

ひらくん
Posted byひらくん

Comments 0

There are no comments yet.

Leave a reply