我是Ruby的新手。經過一番重構之後,我回到了這個位置。有沒有更好的方法來寫這個?在Ruby中寫這個更好的方法是什麼?
51 def tri_num?(n)
52 i = 1
53 while i < n
54 return i if i * (i + 1)/2 == n
55 i += 1
56 end
57 raise InvalidTree
58 end
我是Ruby的新手。經過一番重構之後,我回到了這個位置。有沒有更好的方法來寫這個?在Ruby中寫這個更好的方法是什麼?
51 def tri_num?(n)
52 i = 1
53 while i < n
54 return i if i * (i + 1)/2 == n
55 i += 1
56 end
57 raise InvalidTree
58 end
什麼直接解決了嗎?
def tri_num? n
i = (0.5*(-1.0 + Math.sqrt(1.0 + 8.0*n))).to_i
if i*(i+1)/2 == n
return i
else
raise InvalidTree
end
end
雖然我不知道tri_num?
是不是一個好名字。通常以一個以?結尾的函數應該返回true
或false
。
我不知道這個公式,任何參考? – CamelCamelCamel
我只是做了一個小代數,並解決[二次方程](http://en.wikipedia.org/wiki/Quadratic_equation)我^ 2 +我 - 2 * n = 0。 – dantswain
我希望我有數學技能。好的解決方案 – CamelCamelCamel
是的。
def tri_num?(n)
1.upto(n-1) do |i|
return i if i * (i + 1)/2 == n
end
raise InvalidTree
end
+1 :)你打我幾秒 – Tilo
這不是浪費週期嗎?說n是11,這不是一個三角形數字:這是直到第10個三角形數字是55,高於n。 – CamelCamelCamel
我的算法與您最初在問題中發佈的算法基本相同,但它只是寫得更簡潔。您的算法具有相同的低效率。我注意到它,但沒有去改善它。在適當的時候發出「break」聲明會使該算法在引發異常的情況下更有效。 –
我認爲一樣dantswain,基本上反轉公式:
=> i * (i + 1)/2 = n
=> i * (i + 1) = 2*n
=> i^2 + i = 2*n
=> i^2 + i -2*n = 0
而對於上述的解決方案是:
i = (-1 +- sqrt(1+8n))/2
在這裏我不考慮-
的解決方案,因爲它會給n大於0的任何值賦予負數,最後的代碼是:
def tri_num?(n)
i = (-1 + Math.sqrt(1 + 8*n))/2.0
return i.to_i if i == i.to_i
raise InvalidTree
end
define'better'?你的意思是視覺上還是速度?因爲如果你關心的是後者,那麼while循環可能是最快的。我同意這不是太具有吸引力。查看Fixnum#次:'n.times {| i |返回我如果我*(i + 1)/ 2 == n'例如 –