用 Haskell 求解 ACM 競賽題(5):for 迴圈
阿新 • • 發佈:2018-12-20
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 中,可以用列表推導式解決資料遍歷、資料暴力窮舉型別的問題。