如何计算数字列表中的偶数和奇数

时间:2018-03-24 14:33:11

标签: haskell

我想编写一个函数,告诉我列表中偶数和奇数出现的次数。例如,如果我的列表是[1,2,3,4,5],我希望它返回(2,3)。

这是我到目前为止所拥有的

counteven :: [Integer] -> Integer
counteven [] = 0
counteven (x:xs) 
     |(x `div` 2) == 0 = 1 + counteven xs
     |otherwise = counteven xs

countodd :: [Integer] -> Integer
countodd [] = 0
countodd (x:xs) 
     |(x `div` 2) /= 0 = 1 + countodd xs
     |otherwise = countodd xs

oddsAndEvens :: [Integer] -> (Integer,Integer)
oddsAndEvens (x:xs) = ((counteven(x:xs)),(countodd(x:xs)))

它确实在我的文本编辑器上运行但是我得到了奇怪的结果 有人可以帮我解决问题所在吗?

4 个答案:

答案 0 :(得分:3)

你有两个问题。

问题1:div vs mod

div除以数字。 mod取其余部分。例如,div 6 2 = 3mod 6 2 = 0

您错误地使用了div。那应该是mod,所以你的第一个函数应该是:

counteven :: [Integer] -> Integer
counteven [] = 0
counteven (x:xs)
  | x `mod` 2 == 0   = 1 + counteven xs -- NOTE: `mod` not `div`!
  | otherwise        = counteven xs

我确信你可以自己修复countodd这个例子。

问题二:过度限制模式匹配。

您的最终功能也存在问题:

oddsAndEvens :: [Integer] -> (Integer, Integer)
oddsAndEvens (x:xs) = (counteven (x:xs), countodd (x:xs))

参数(x:xs)仅在非空列表上匹配模式,因此oddsAndEvens []将产生错误,因为您尚未定义其行为。

应该

oddsAndEvens :: [Integer] -> (Integer, Integer)
oddsAndEvens xs = (counteven xs, countodd xs)

由于xs匹配任何内容,因此该函数现在可用于空列表和非空列表。

答案 1 :(得分:2)

另一种解决方案:

import           Data.List         (partition)
import           Data.Tuple.Extra  (both)

countEvenAndOdd :: Integral a => [a] -> (Int, Int)
countEvenAndOdd x = both length (partition even x)

答案 2 :(得分:0)

Prelude有一个函数odd :: Int -> Bool,可以检查数字是否为奇数。因此,过滤所有奇数并找到它的大小。所有其他数字都是偶数。

c :: [Int] -> (Int, Int)
c as = (odds, evens)
    where odds  = length $ filter odd as
          evens = length as - odds

答案 3 :(得分:0)

您只需确定列表中偶数/奇数之一的计数。你有列表的长度。列表的长度减去列表中偶数/奇数之一的计数是列表中的余数或其他数字。

[[l1,l2] | l1 <-[length [ n | n <- l, mod n 2 == 0]], l2 <-[length l - l1]]!!0

具有嵌套列表理解的一行,无需执行分配。

 function calculateDistance()
            {
                var pointx1 = parseInt(document.getElementById("pointx1").value);
                var pointy1 = parseInt(document.getElementById("pointy1").value);
                var pointx2 = parseInt(document.getElementById("pointx2").value);
                var pointy2 = parseInt(document.getElementByID("pointy2").value);
          
                var distance = Math.sqrt(Math.Pow((pointx1-pointx2),2)+Math.Pow((pointy1-pointy2),2));

                window.alert("Distance: "+distance);

            }    

产量相同。