作者: Kazuhiro NISHIYAMA
日時: 2006/6/30(19:25)
西山和広です。

>>> Fri, 30 Jun 2006 11:25:04 +0900 (JST) の刻に
>>> kbk@...(Bruce.) 氏曰く
> 
> 某所でRubyではないのですが(Java)、「再帰を使って2番目に大きい要素を求めよ」
> といった感じのお題を見かけました。今ひとつ明確でない部分があるのですが、多分
> 配列(リスト)が対象でソートせずに求めろということだろうと判断して
> ちょっとRubyでやってみました。

> getmaxをもっと関数型言語っぽく書けよというおしかりは甘んじて受けますが(^^;、
> 2番目を取り出すのに2回getmaxするのは美しくありません。
> なんかいい手はないでしょうか?

最大値2つだけを取って再帰していくようにしてみたら、
以下のようになりました。

要素が2個未満のときは2番目がないということでnilを
返すようにしてみました。


#!/usr/bin/ruby

def getmax(ary)
  ary.max
end

#def getmax2(*ary)
#  [ary.max, (ary-[ary.max]).max]
#end
def getmax2(a, b, c=nil, *rest)
  if a < b
    a,b = b,a
  end
  return [a,b] if c.nil?
  if b < c
    b = c
  elsif a < c
    a = c
  end
  getmax2(a,b,*rest)
end

if false
  p getmax2(1,2,3,4,5)
  p getmax2(5,4,3,2,1)
  p getmax2(1,5,3,4,2)
end

def get2nd(ary)
  case ary.size
  when 0,1
    return nil
  when 2
    return ary.min
  else
    getmax2(*ary)[1]
  end
end

ary = []
DATA.each do |e|
  ary << e.to_i
end

puts ary
puts "###"
print "#{getmax(ary)}, #{ary.sort[-1]}\n"
print "#{get2nd(ary)}, #{ary.sort[-2]}\n"

#made by
# ruby -e "srand(4649); (1..15).each{|e| puts ((rand()*1000).to_i)}"
__END__
238
212
889
625
870
566
814
704
389
50
679
277
794
314
240



-- 
|ZnZ(ゼット エヌ ゼット)
|西山和広(Kazuhiro NISHIYAMA)