1. 程式人生 > >用 Haskell 求解 ACM 競賽題(5):for 迴圈

用 Haskell 求解 ACM 競賽題(5):for 迴圈

for 迴圈

考慮這樣一個問題: 列印 1, 2, 3,…, 10, 每個 佔 一行。 本著“ 解決問題 第一” 的思想, 很容易寫出程式: 10 條 printf 語句就可以了。 或者也可以寫一條, 每個數 後面加 一個“\ n” 換行符。 但如果把 10 改成 100 呢? 1000 呢? 甚至這個重複次數是可變的:“ 輸入正整數 n, 列印 1, 2, 3,…, n, 每個佔一行。” 又怎麼辦呢? 這時可以使用 for 迴圈。

程式 2-1: 輸出 1, 2, 3,…, n 的 值

C語言程式碼:

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

Haskell 程式碼:

nums 0 = []
nums n = (nums (n - 1)) ++ [n]

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

Haskell 語言採用遞迴定義實現 C 語言迴圈語句功能。

完全平方數

問題 aabb 輸出所有形如 aabb 的 4 位完全平方數(即前兩位數字相等, 後兩位數字也相等)。

【分析】分支和迴圈結合在一起時功能強大: 下面列舉所有可能的 aabb, 然後判斷它們是否 為完全平方數。 注意, a 的範圍是 1 ~ 9, 但 b 可以是 0。 主程式如下:

C語言程式碼:

#include <stdio.h> 
#include <math.h> 
int main() { 
	for (int a = 1; a <= 9; a++) 
		for(int b = 0; b <= 9; b++) { 
			int n = a* 1100 + b* 11; //這裡 才 開始 使用 n, 因此 在這裡 定義
			int m = floor(sqrt(n) + 0. 5); 
			if (m*m == n) printf("% d\ n", n); 
		} 
	return 0;
}

Haskell語言程式碼:

isSqr' n m
    | m == 0    = False
    | n == m*m  = True
    | otherwise = isSqr' n (m-1)
isSqr n = isSqr' n (n-1)
    
main = do return [n | a<-[1..9], b<-[0..9], let n = 1100*a+11*b, isSqr n]

在 haskell 中,可以用列表推導式解決資料遍歷、資料暴力窮舉型別的問題。