Function 用户输入的平均值
我想让用户输入一个数字列表,然后找到平均值。然而,在查找示例之后,我没有发现任何与我所做的匹配的示例,因为我可以在列表中找到2-100个数字。欢迎提供任何帮助/建议 下面是我的工作代码Function 用户输入的平均值,function,haskell,average,Function,Haskell,Average,我想让用户输入一个数字列表,然后找到平均值。然而,在查找示例之后,我没有发现任何与我所做的匹配的示例,因为我可以在列表中找到2-100个数字。欢迎提供任何帮助/建议 下面是我的工作代码 main = do putStrLn "Enter how many numbers:" listlen <- getLine if ((read listlen) <= 100) -- read converts a string to a number then do
main = do
putStrLn "Enter how many numbers:"
listlen <- getLine
if ((read listlen) <= 100) -- read converts a string to a number
then do
putStrLn "Enter a String of numbers:"
--numberString <- getLine
numberString<- getLine
let ints = map read (words numberString) :: [Int]
putStrLn("The List: " ++(numberString))
putStrLn("The average: ")
putStrLn("Number of values greater than average: ")
else do
putStrLn " Error: listlen must be less than or = to 100"
main
main=do
putStrLn“输入多少个数字:”
listlenlistlen::[a]->Int
listlen xs=go 0 xs--0=累加器的初始值
其中go s[]=s——返回累加器
go s(a:as)=go(s+1)as——计算累加器的下一个值
sumx::[a]->Int
sumx xs=go 0 xs
去哪里s[]=s
go s(a:as)=go。。。如同空白的空白……和递归
lenAndSum::[a]->(Int,Int)
lenAndSum xs=go(0,0)xs--(0,0)=两个蓄能器的初始值
其中go(s1,s2)[]=(s1,s2)——在末端返回两个蓄能器
去(s1,s2)(a:as)=去。。。作为一种练习
main=do
putStrLn“输入多少个数字:”
listlen好的,这是家庭作业,但当你不得不在Haskell做作业时,家庭作业可能会很难。我将试着一步一步地解释你能做什么
很高兴知道
首先,Haskell是功能性的。你可以找到“functional”的不同定义,但基本上你可以把它看作是语言的一种属性:一切都是不变的(没有副作用)
其次,您可以通过在终端中键入ghci
来启动:
jferard@jferard-Z170XP-SLI:~$ ghci
GHCi, version 8.0.2: http://www.haskell.org/ghc/ :? for help
Prelude> :set +m -- enable parsing of multiline commands
Prelude> -- type the expression you want to evaluate here
递归
如何计算列表中元素的总和?在命令式语言中,您将执行类似于Python的操作:
只要稍加想象,你就可以说sum[]=0
。所以我们可以用Haskell来写:
sum [] = 0
sum (x:xs) = x + sum xs
-- sum [1, 2, 3, 5] == 11
(x:xs)
的意思是:x
(head
),后面是列表xs
(tail
)。如果您已经理解了这一点,您就知道在许多情况下如何避免副作用:只需调用另一个函数来完成其余的工作。(注意:如果您了解堆栈,可以想象引擎盖下会发生什么。)
现在,如何计算列表的长度?在类似Python的语言中,您可以执行以下操作(忘记len(…)
):
褶皱
计算总和和长度非常常见,因此它们是Haskell中的内置函数。但有一点更重要:如果仔细检查这两个函数,您会注意到以下模式:
f [] = <initial value>
f (x:xs) = g(f xs, x)
(关于curryfication的注意事项:1.有一天您可能会了解到Haskell函数总是使用一个参数,但这不是重点。2.您可以删除两边的X:sum=foldl(+)0
)
使用scanl
,您可以通过某种方式“调试”foldl
:
Prelude> scanl (+) 0 [1,2,3,5]
[0,1,3,6,11]
gtAvg xs = foldl (\acc x -> if fromIntegral x>average xs then acc+1 else acc) 0 xs
length
更复杂,因为您没有内置函数g(f xs,x)=1+f xs
。您可以使用:\acc x->1+acc
,其中acc
是当前值:
length xs = foldl (\acc x -> 1 + acc) 0 xs
你的问题
平均的
让我们尝试使用内置的sum
和length
函数编写average
:
Prelude> average xs = sum xs / length xs
<interactive>:1:14: error:
• Could not deduce (Fractional Int) arising from a use of ‘/’
...
这意味着/
将采用分数
s。因此,工作是:将整数转换成分数
average xs = fromIntegral (sum xs) / fromIntegral (length xs)
-- average [1, 2, 3, 5] == 2.75
大于平均值的值的数目
现在,值的数量大于平均值。在类似Python的语言中,您将编写:
c = 0
for every x in xs:
if x > avg:
c <- c + 1
你看,有东西不见了。在命令式版本中,如果x是这样,您发现了什么看起来很接近但并不完美的匹配?为什么你认为它对你不起作用?这里的很多人都可以为你写一个解决方案,但是为了帮助你学习,看看你在想什么和你尝试过什么是很重要的。我试过以下方法:--但是我不知道如何将它用于最多100个可以输入的数字我已经看过了这里几乎所有的Haskell average相关帖子,似乎没有一篇文章的长度是基于用户输入的。。所以我不能硬编码长度。第一个链接对于任何大小的列表都可以,不管是否由用户给出。这看起来像是一个家庭作业问题。向你的教授或助教寻求帮助可能更合适。当然,你走对了方向。有一些有效的方法可以填补这些空白来回答您的问题(不过,您必须修复这些类型)。另外,要小心剽窃:虽然Stack Overflow不介意您使用其答案中的代码,但Stack Overflow的授权和您的教授都会要求您引用您使用的任何非您自己的代码。另外,您已经认为您知道列表的长度,因此不必计算它。
Prelude> foldl (+) 0 [1,2,3,5]
11 -- (((0+1)+2)+3)+5
Prelude> scanl (+) 0 [1,2,3,5]
[0,1,3,6,11]
length xs = foldl (\acc x -> 1 + acc) 0 xs
Prelude> average xs = sum xs / length xs
<interactive>:1:14: error:
• Could not deduce (Fractional Int) arising from a use of ‘/’
...
Prelude> :t (/)
(/) :: Fractional a => a -> a -> a
average xs = fromIntegral (sum xs) / fromIntegral (length xs)
-- average [1, 2, 3, 5] == 2.75
c = 0
for every x in xs:
if x > avg:
c <- c + 1
gtAvg [] = 0
gtAvg (x:xs) = (if x>avg then 1) + sum xs -- WRONG
gtAvg [] = 0
gtAvg (x:xs) = (if x>avg then 1 else 0) + gtAvg xs
gtAvg' [] _ = 0
gtAvg' (x:xs) avg = (if fromIntegral x>avg then 1 else 0) + gtAvg' xs avg
-- gtAvg' [1, 2, 3, 5] (average [1, 2, 3, 5]) == 2
gtAvg xs = gtAvg' xs (average xs)
-- gtAvg [1, 2, 3, 5] == 2
gtAvg xs = foldl (\acc x -> if fromIntegral x>average xs then acc+1 else acc) 0 xs
Prelude> filter (>2.75) [1, 2, 3, 5]
[3.0,5.0]
gtAvg xs = length $ filter (\x -> fromIntegral x >average xs) xs
Prelude> sum $ map (**2) [1, 2, 3, 5]
39.0
gtAvg xs = length $ filter (>average xs) $ map fromIntegral xs
gtAvg xs = length [x | x<-xs, fromIntegral x>average xs]