Haskell 从整数中删除数字
我遇到了一个家庭作业问题: 输入一个大于或等于0的整数。把它乘以5,再把6加到乘积上,再乘以4,再加9,再乘以5。然后,去掉最后两位数字并减去1。输出答案 这是我的密码:Haskell 从整数中删除数字,haskell,Haskell,我遇到了一个家庭作业问题: 输入一个大于或等于0的整数。把它乘以5,再把6加到乘积上,再乘以4,再加9,再乘以5。然后,去掉最后两位数字并减去1。输出答案 这是我的密码: 1 main = do 2 putStrLn "enter a non-negative integer: " 3 input <- getLine 4 let i = (read input :: Int) 5 print ((((i * 5) + 6) * 4 + 9) *
1 main = do
2 putStrLn "enter a non-negative integer: "
3 input <- getLine
4 let i = (read input :: Int)
5 print ((((i * 5) + 6) * 4 + 9) * 5)/100-1
这一部分很奇怪:“函数“((i*5)+6)*4+9)*5”应用于两个参数”,为什么haskell将其解释为函数?删除任意位置的数字是一个有趣的问题。通过转换为字符串并执行字符串操作,然后作为Int读回,这可能是最容易做到的。由于
Int
实现了Show
和Read
,您可以执行以下操作:
type Digit = Int
removeDigits :: [Digit] -> Int -> Int
removeDigits digits = read . go 1 . show
where
go _ [] = []
go i (c:cs) | i `elem` digits = go cs (i+1)
| otherwise = c : go cs (i+1)
-- N.B. I chose 1-indexing here instead of 0-indexing because of your word choice
-- "remove the first, second, and sixth digits" maps naturally to [1, 2, 6],
-- though programmers may find that off-putting. YMMV.
removeDigits
此处可以重新编写为
read [c | (i, c) <- zip [1..] (show n), i `notElem` digits]
read[c |(i,c)删除任意位置的数字是一个有趣的问题。通过转换为字符串并执行字符串操作,然后作为Int读回,这可能是最容易做到的。由于Int
实现了Show
和read
,您可以:
type Digit = Int
removeDigits :: [Digit] -> Int -> Int
removeDigits digits = read . go 1 . show
where
go _ [] = []
go i (c:cs) | i `elem` digits = go cs (i+1)
| otherwise = c : go cs (i+1)
-- N.B. I chose 1-indexing here instead of 0-indexing because of your word choice
-- "remove the first, second, and sixth digits" maps naturally to [1, 2, 6],
-- though programmers may find that off-putting. YMMV.
removeDigits
此处可以重新编写为
read [c | (i, c) <- zip [1..] (show n), i `notElem` digits]
read[c|(i,c)有人能解释一下错误的含义吗?
第一行中的优先级是非中缀函数(如/
)通常比普通函数具有更高的优先级,因此print(…)/100
相当于(print…)/100
,这显然是有问题的。您可以将所有函数都用括号括起来,或者使用$
函数:
print $ ((((i * 5) + 6) * 4 + 9) * 5) / 100 - 1
现在,由于您已将i
约束为Int
,这仍然会给出一个错误:/
仅为分数型
类型类的实例定义,而Int
不是。您想要整数除法、div
或quot
,它只对整数型
进行操作(其中Int
是一个实例)并根据需要执行截断:
print $ ((((i * 5) + 6) * 4 + 9) * 5) `div` 100 - 1
请注意倒勾(`),它允许在中缀中使用普通函数。您可以这样写:
print $ (div ((((i * 5) + 6) * 4 + 9) * 5) 100) - 1
但是括号让人很难理解
还有比除数截断更好的解决方案吗?
一般来说,可能不会,但是,这个特定的等式将始终为您提供与输入相同的结果,因此您可以只写:
main = getLine >>= print
如何删除任意位置的数字?
转换为字符串并删除字符可能是您的最佳选择。类似于以下的操作将起作用,尽管它可能有点密集:
removeDigits :: [Int] -> Int -> Int
removeDigits indices x = read . reverse . filterIndices indices . reverse . show $ x
filterIndices :: [Int] -> [a] -> [a]
filterIndices inds elems = map snd . filter ((`notElem` inds) . fst) . zip [1..] $ elems
请注意,这将最后一个数字视为“第一个”数字-用数字表示数字更为自然
(在我看来)更易于阅读的现有代码表示形式是:
transform = (subtract 1) . (`quot` 100) . (*5) . (+9) . (*4) . (+6) . (*5)
通过这种书写方式,构图凌驾于算术优先法则之上,让我们按照它的阅读方式来书写(“乘以5,加上6,乘以4,…)。我们必须使用减去1
,因为-1
被解释为文本值-1
,而不是一元函数。有人能解释错误的含义吗?
第一行中的优先级是非中缀函数(如/
)通常比普通函数具有更高的优先级,因此print(…)/100
相当于(print…)/100
,这显然是有问题的。您可以将所有函数都用括号括起来,或者使用$
函数:
print $ ((((i * 5) + 6) * 4 + 9) * 5) / 100 - 1
现在,由于您已将i
约束为Int
,这仍然会给出一个错误:/
仅为分数型
类型类的实例定义,而Int
不是。您想要整数除法、div
或quot
,它只对整数型
进行操作(其中Int
是一个实例)并根据需要执行截断:
print $ ((((i * 5) + 6) * 4 + 9) * 5) `div` 100 - 1
请注意倒勾(`),它允许在中缀中使用普通函数。您可以这样写:
print $ (div ((((i * 5) + 6) * 4 + 9) * 5) 100) - 1
但是括号让人很难理解
还有比除数截断更好的解决方案吗?
一般来说,可能不会,但是,这个特定的等式将始终为您提供与输入相同的结果,因此您可以只写:
main = getLine >>= print
如何删除任意位置的数字?
转换为字符串并删除字符可能是您的最佳选择。类似于以下的操作将起作用,尽管它可能有点密集:
removeDigits :: [Int] -> Int -> Int
removeDigits indices x = read . reverse . filterIndices indices . reverse . show $ x
filterIndices :: [Int] -> [a] -> [a]
filterIndices inds elems = map snd . filter ((`notElem` inds) . fst) . zip [1..] $ elems
请注意,这将最后一个数字视为“第一个”数字-用数字表示数字更为自然
(在我看来)更易于阅读的现有代码表示形式是:
transform = (subtract 1) . (`quot` 100) . (*5) . (+9) . (*4) . (+6) . (*5)
通过这种书写方式,构图凌驾于算术优先法则之上,让我们按照它的阅读方式来书写(“乘以5,加上6,乘以4,…)。我们必须使用subtract 1
,因为-1
被解释为文本值-1
,而不是一元函数。使用div
,而不是/
。整数除法是div
,而不是//code>@chepner,如果您省略了所述的前提条件,正确的除法操作将是
quot
,而不是div
。如果你想像操作符一样使用div,你必须把它放在反引号中。仅供参考,你可以使用下面的代码:transform=(减法1)。(`quot`100)。(*5)。(+9)。(*4)。(+6)。(*5)
,尽管答案是“还有比用除数表示更好的解决方案吗?”已在my中给出,因此可能不需要在此处重复。使用div
,而不是//code>。整数除法是div
,而不是//code>@chepner,如果省略所述的前置条件,正确的除法操作将是quot
,而不是div
。您必须将div
放入