计算列表中的整数出现次数

时间:2017-11-30 15:04:54

标签: haskell

我正在尝试执行以下操作:
我正在编写的函数列出了0-6中范围内的[(x,y),(i,j)...]元组列表 我想返回[Int],其中每个元素都是其中有多少元素 列表中可以看到相应的数字 例如[(0,1), (1,2), (2,3)]会返回[1, 2, 2, 1, 0, 0, 0]

换句话说,一个0,两个1,两个2的1三,没有4s,5s或6s

countNumbers :: [(Int, Int)] -> [Int]  
countNumbers [] = [0, 0, 0, 0, 0, 0, 0]

但我不知道如何解决这个问题,因为我对Haskell有点新鲜 编辑 - 我找到了解决方案 - 请告诉我是否有更简洁的编码方式!

type ProbabilityMatrix = (Int,Int,Int,Int,Int,Int,Int)
-- converts list of tuples into list of ints as suggested
tupleToList :: [(Int, Int)] -> [Int]  
tupleToList ((a,b):xs) = a : b : tupleToList xs  
tupleToList _          = []    

tupleToList2 :: [Int] -> ProbabilityMatrix -> ProbabilityMatrix  
tupleToList2 [] list = list  
tupleToList2 (x : xs) (zero, one, two, three, four, five, six)  
  | x == 0 =  tupleToList2 xs (zero + 1, one, two, three, four, five, six)  
  | x == 1 = tupleToList2 xs (zero, one + 1, two, three, four, five, six)  
  | x == 2 = tupleToList2 xs (zero, one, two + 1, three, four, five, six)  
  | x == 3 = tupleToList2 xs (zero, one, two, three + 1, four, five, six)  
  | x == 4 = tupleToList2 xs (zero, one, two, three, four + 1, five, six)  
  | x == 5 = tupleToList2 xs (zero, one, two, three, four, five + 1, six)  
  | x == 6 = tupleToList2 xs (zero, one, two, three, four, five, six + 1)  
  | otherwise = tupleToList2 xs (zero + 1, one, two, three, four, five, six)   

2 个答案:

答案 0 :(得分:3)

如何为每个元组创建Int的结果列表,然后使用Sum函数将它们合并在一起。您至少需要两个带签名的功能:

tupleToList :: (Int, Int) -> [Int]

sumLists :: [Int] -> [Int] -> [Int]

第一个将检测元组中的两个项目,并为其生成相应的列表,例如tupleToList (4, 2) -> [0,0,1,0,1,0,0]

第二个函数将通过在相同索引处对2个计数器求和来合并两个整数列表,例如: sumLists [0,1,1,0,1] [1,1,0,0,0] -> [1,2,1,0,1]。您可以递归执行此操作,直到最终得到1个问题的答案列表。

您为元组列表中的每个元素执行tupleToList(可能使用map),然后通过迭代执行sumLists 2个列表来合并结果列表(可能与foldl

这种方法相当幼稚,可能会为更大的输入而缓慢运行。

答案 1 :(得分:0)

您可以尝试此解决方案:

-- flattens a list of tuples into a list
flatten :: (Num a) => [(a, a)] -> [a]
flatten xs = concat [[a,b] | (a, b) <- xs]

-- updates list element at a position
update_list :: (Num a) => Int -> [a] -> [a]
update_list n xs = take n xs ++ [(xs !! n) + 1] ++ drop (n + 1) xs

-- performs count of numbers
count_numbers :: [(Int, Int)] -> [Int]
count_numbers xs = go (flatten xs) acc
    where go [] acc = acc
          go (x:xs) acc = go xs (update_list x acc)
          acc = replicate 7 0

首先展开列表:

*Main> flatten [(0,1), (1,2), (2,3)]
[0,1,1,2,2,3]

然后更新某个位置的列表:

*Main> update_list 1 (replicate 7 0)
[0,1,0,0,0,0,0]

与您的函数tupleToList2类似地执行列表元素的计数,其中存储和更新数字计数的累加器:

*Main> count_numbers [(0,1), (1,2), (2,3)]
[1,2,2,1,0,0,0]
*Main> count_numbers [(0,1), (1,2), (2,4)]
[1,2,2,0,1,0,0]
*Main> count_numbers [(0,0), (1,0), (3,6)]
[3,1,0,1,0,0,1]