简体   繁体   English

计算整数 Haskell 中的奇数位数

[英]Count number of odd digits in Integer Haskell

I'm trying to make program which counts the number of odd digits in integer using Haskell.我正在尝试制作使用 Haskell 计算整数奇数位数的程序。 I have ran into problem with checking longer integers.我在检查更长的整数时遇到了问题。 My program looks like this at the moment:我的程序现在是这样的:

oddDigits:: Integer -> Int
x = 0
oddDigits i
   | i `elem` [1,3,5,7,9] = x + 1
   | otherwise = x + 0

If my integer is for example 22334455 my program should return value 4, because there are 4 odd digits in that integer.例如,如果我的整数是 22334455,我的程序应该返回值 4,因为该整数中有 4 个奇数。 How can I check all numbers in that integer?如何检查该整数中的所有数字? Currently it only checks first digit and returns 1 or 0. I'm still pretty new to haskell.目前它只检查第一位数字并返回 1 或 0。我对 haskell 还是很陌生。

In order to solve such problems, you typically split this up into smaller problems.为了解决此类问题,您通常会将其分解为较小的问题。 A typical pipeline would be:一个典型的管道是:

  1. split the number in a list of digits;将数字拆分为数字列表;
  2. filter the digits that are odd;过滤奇数; and
  3. count the length of the resulting list.计算结果列表的长度。

You thus can here implement/use helper functions.因此,您可以在这里实现/使用辅助函数。 For example we can generate a list of digits with:例如,我们可以生成一个数字列表:

digits' :: Integral i => i -> [i]
digits' 0 = []
digits' n = r : digits' q
    where (q, r) = quotRem n 10

Here the digits will be produced in reverse order, but since that does not influences the number of digits, that is not a problem.这里的数字将以相反的顺序产生,但由于这不会影响数字的数量,所以这不是问题。 I leave the other helper functions as an exercise.我将其他辅助函数留作练习。

You can first convert the integer 22334455 to a list "22334455" .您可以先将整数22334455转换为列表"22334455" Then find all the elements satisfying the requirement.然后找出所有满足要求的元素。

import Data.List(intersect)

oddDigits = length . (`intersect` "13579") . show

Here's an efficient way to do that:这是一种有效的方法:

oddDigits :: Integer -> Int
oddDigits = go 0
  where
    go :: Int -> Integer -> Int
    go s 0 = s
    go s n = s `seq` go (s + fromInteger r `mod` 2) q
      where (q, r) = n `quotRem` 10

This is tail-recursive, doesn't accumulate thunks, and doesn't build unnecessary lists or other structures that will need to be garbage collected.这是尾递归的,不会累积 thunk,也不会构建不必要的列表或其他需要垃圾收集的结构。 It also handles negative numbers correctly.它还可以正确处理负数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM