我是Haskell的新手,几天前开始学习,我对我正在尝试的功能有疑问。
我想创建一个函数来验证 x 是否是 n 的因子(例如:375具有以下因素:1,3,5,15,25, 75,125和375),然后删除1然后删除数字本身,最后验证该列表中奇数的数量是否等于偶数的数量!
我想过制作这样的函数来计算第一部分:
factor n = [x | x <- [1..n], n `mod`x == 0]
但如果我把它放在提示符上,它会说Not in scope 'n'
。想法是输入一个像375这样的数字,以便计算清单。我做错了什么?我已经在书中看到了这样的提示功能。
然后采取我所说的元素,我正在考虑做尾巴,然后初始化到列表中。你认为这是个好主意吗?
最后我想到制作一个if语句来验证最后一部分。例如,在Java中,我们会做类似的事情:
(x % 2 == 0)? even++ : odd++; // (I'm a beginner to Java as well)
然后如果偶数=奇数则会说所有条件都经过验证(我们有一定数量的偶数等于奇数)
但是在Haskell中,由于变量是不可变的,我该如何处理++事物呢?
感谢您提供的任何帮助:)
答案 0 :(得分:4)
这个小功能完成了你想要实现的一切:
f n = length evenFactors == length oddFactors
where evenFactors = [x | x <- [2, 4..(n-1)], n `mod` x == 0]
oddFactors = [x | x <- [3, 5..(n-1)], n `mod` x == 0]
答案 1 :(得分:3)
如果“命令行”是ghci,那么你需要
let factor n = [x | x <- [2..(n-1)], n `mod` x == 0]
在这种特殊情况下,您不需要将[1..n]范围仅限于1和n - 范围从2到(n-1)。
你可以简单地使用分区来使用布尔谓词来分割除数列表:
import Data.List
partition odd $ factor 10
为了学习如何编写像partition
这样的函数,请研究递归。
例如:
partition p = foldr f ([],[]) where
f x ~(ys,ns) | p x = (x:ys,ns)
f x ~(ys,ns) = (ys, x:ns)
(这里我们需要使用“〜”懒惰模式匹配元组,以确保在构造右边的元组之前不评估模式)。
简单计数可以更简单地实现:
let y = factor 375
(length $ filter odd y) == (length y - (length $ filter odd y))
答案 2 :(得分:2)
创建一个文件source.hs,然后从ghci命令行调用:l source
加载source.hs中定义的函数。
要解决您的问题,这可能是您的步骤后的解决方案:
-- computers the factors of n, gets the tail (strips 1)
-- the filter functions removes n from the list
factor n = filter (/= n) (tail [x | x <- [1..n], n `mod` x == 0])
-- checks if the number of odd and even factors is equal
oe n = let factors = factor n in
length (filter odd factors) == length (filter even factors)
致电oe 10
返回True
,oe 15
返回False
答案 3 :(得分:1)
(x % 2 == 0)? even++ : odd++;
我们Data.List
partition :: (a -> Bool) -> [a] -> ([a], [a])
函数
所以我们可以划分赔率
> let (odds,evens) = partition odd [1..]
> take 10 odds
[1,3,5,7,9,11,13,15,17,19]
> take 10 evens
[2,4,6,8,10,12,14,16,18,20]
答案 4 :(得分:0)
以下是使用理解的factor
尝试的最小修复:
factor nn = [x | n <- [1..nn], x <- [1..n], n `mod`x == 0]