我正在解決 Haskell 中的一個練習問題,我試圖計算 2 個給定整數之間的回文數。個位數是回文數。我試過用輔助函式解決它,但我不能讓它從主函式中取較小的數字。任何幫助,將不勝感激!到目前為止,我輸入了這個:
main :: IO()
main = do
print $ countPalindromes 5 13 == 5 -- 6 7 8 9 11
print $ countPalindromes 13 5 == 5 -- 6 7 8 9 11
rev :: Int -> Int
rev n = helper n 0
where
helper :: Int -> Int -> Int
helper 0 result = result
helper n result = helper (div n 10) (result * 10 mod n 10)
isPalindrome :: Int -> Bool
isPalindrome x = rev x == x
countPalindromes :: Int -> Int -> Int
countPalindromes a b
| a > b = helper b a 0
| otherwise = helper a b 0
where
helper :: Int -> Int -> Int -> Int
helper a b count
| a <= b && isPalindrome (a - 1) = count 1
| otherwise = helper (a - 1) b count
uj5u.com熱心網友回復:
那不是你的問題。問題是helper a b count只回傳count 1ifa是回文,而不檢查 if a 1,a 2等是否也是回文。當第一個數字是回文時,它回傳0 1 == 1并完成。(你的定義helper也是錯誤的計算方式;如果你想成為假,它會遞減 a而不是遞增。)a <= b
helper需要遞回是否a是回文;唯一的區別在于它的第三個引數的值。
helper a b count | a > b = count -- base
| isPalindrome a = helper (a 1) b (count 1)
| otherwise = helper (a 1) b count
請注意,b永遠不會改變;它不需要成為helper. 相反,您可以進行遞回呼叫countPalindromes以確保a < b:
countPalindromes :: Int -> Int -> Int
countPalindromes a b
| a > b = countPalindromes b a
| otherwise = helper a 0
where
helper :: Int -> Int -> Int
helper a count
| a > b = count -- base case
| isPalindrom a = helper (a 1) (count 1)
| otherwise = helper (a 1) count
尾遞回在 Haskell 中也不是很重要。你可以寫得helper更自然
helper a | a > b = 0
| isPalindrome a = 1 helper (a 1)
| otherwise = helper (a 1)
還要注意,isPalindrome回傳Trueor之間的唯一區別False是您是否將1or添加0到遞回回傳值。您可以使用以下方法捕獲它fromEnum:
helper a | a > b = 0
| otherwise = (fromEnum (isPalindrome a)) helper (a 1)
作為練習,請注意您根本不需要顯式遞回。您可以使用filter來獲取回文范圍內的值,然后簡單地計算結果串列中值的數量。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/439493.html
