1. 程式人生 > >用 Haskell 求解 ACM 競賽題(7):階乘之和

用 Haskell 求解 ACM 競賽題(7):階乘之和

問題:階乘 之和
輸入 n, 計算 S = 1! + 2! + 3! +… + n! 的末 6 位( 不含前導 0)。 n106n ≤ 10^6, n! 表示前 n 個正整數之積。
樣例輸入: 10
樣例輸出: 37913

【分析】 這個任務並不難, 引入累加變數 S 之後, 核心演算法只有“ for( int i = 1; i < = n; i + +) S + = i!”。 不過, C 語言並沒有階乘運算子, 所以這句話只是虛擬碼, 而不是真正的程式碼。 事實上, 還需要一次迴圈來計算 i!, 即“ for( int j = 1; j < = i; j + +) factorial* = j;”。

C語言程式碼:

#include <stdio.h> 
int main() { 
	int n, S = 0; 
	scanf("% d", &n); 
	for( int i = 1; i <= n; i++) { 
		int factorial = 1; 
			for( int j = 1; j <= i; j++) factorial *= j; 
			S += factorial; 
	} 
	printf("% d\ n", S % 1000000); 
	return 0; 
}

這個演算法在 C 語言因整數溢位大傷腦筋,題目加入了限制,要求結果輸出最後六位。另外,上面程式碼計算效率也成問題,此處不展開討論。在 Haskell 中,處理整數順手得多。下面給出 Haskell 程式碼,無論計算精度還是執行效率,都有很好的表現。

summ' s t i n 
    | i == n    = s+t
    | otherwise = summ' (s+t) (t*(i+1)) (i+1) n

summ 1 = 1
summ n = summ' 0 1 1 n

main = do
    s <- getLine
    return (summ (read s))

給我的感覺是,在求解問題時,Haskell 語言專注於描述問題本身如何求解,C 語言則陷入計算機資料各種轉換的細節中。