【问题标题】:How can I count Integers in a List of String. Haskell如何计算字符串列表中的整数。哈斯克尔
【发布时间】:2012-11-20 07:46:10
【问题描述】:

有一个字符串列表 ["f", "1", "h", "6", "b", "7"]。

如何在此列表中计算 Int?

现在我有了这个算法,但它不是很好。

import Data.Char
let listOfStrings = ["f", "1", "h", "6", "b", "7"]
let convertedString = "f1h6b7"
let listOfInt = map (\x -> read [x]::Int) (filter (\x -> isDigit x) convertedString)
length listOfInt
Prelude> 3

此外,我无法将 listOfStrings 转换为一个字符串。这个算法甚至不能正常工作

你能帮我优化一下吗?

【问题讨论】:

  • 您想计算列表中表示整数的Strings(以10为底?),我理解正确吗?只有非负整数还是负数?
  • 是的。我想计算表示整数的字符串。他们可能是负面的

标签: string list haskell


【解决方案1】:

我发现使用fromEnumBool 转换为0 或1 通常很有用:

import Data.Char

countInts = sum . map (fromEnum . isNumber) . concat

【讨论】:

    【解决方案2】:

    我相信对你来说最好的答案是

    import Data.List (foldl')
    import Data.Char (isNumber)
    countNumb l = foldl' (\x y -> x+1) 0 (filter isNumber l)
    

    这里我们检查 char 是否为数字并计算它们

    附言。这适用于['f', '1', 'h', '6', 'b', '7']

    【讨论】:

      【解决方案3】:

      1) 使用reads :: Reads Int(这个表达式只是reads :: String -> [(Int, String)]的变相)来测试一个字符串是否是一个整数值的表示:

      isNumber :: String -> Bool
      isNumber s = case (reads s) :: [(Int, String)] of
          [(_, "")] -> True
          _         -> False
      

      为什么是reads?因为它返回有关解析过程的附加信息,我们可以从中得出它是否成功的结论。 read :: Int 只会抛出异常。

      2) 然后用它过滤一个字符串列表并取其长度:

      intsCount :: [String] -> Int 
      intsCount = length . filter isNumber
      

      【讨论】:

        【解决方案4】:

        你的代码可以改写为:

        import Data.Char
        
        let listOfStrings = ["f", "1", "h", "6", "b", "7"]
        let convertedString = concat listOfStrings
        let listOfInts = map digitToInt (filter isDigit convertedString)
        
        length listOfInts
        Prelude> 3
        

        要从字符串列表变为单个字符串,只需使用concat。 Concat 接受一个列表列表,并返回一个列表,列表中的所有元素一个接一个,并且由于字符串是Chars 的列表,因此concat 在这种情况下采用@ 列表的列表987654325@,并返回 Char 的单个列表(又名字符串)。

        过滤器从使用\x -> isDigit x 简化为仅使用isDigit。这是完全相同的功能。

        我使用digitToInt而不是\x -> read [x] :: Int读取数字

        注意,如果你只想找到convertedString中的位数,你可以这样做:

        let listOfDigits = filter isDigit convertedString
        
        length listOfDigits
        Prelude> 3
        

        【讨论】:

          【解决方案5】:

          基本原理是

          • 计算具有给定属性的列表中的项目

          一些Prelude函数很容易解决这个问题:

          countItemsWith :: (a -> Bool) -> [a] -> Int
          countItemsWith property list = length $ filter property list
          

          剩下的就是找到一个好的表达式来确定String 是否是整数的表示。我们可以编写自己的测试,但我们也可以为此重用 Prelude 函数,

          isIntegerRepresentation :: String -> Bool
          isIntegerRepresentation s = case reads s :: [(Integer,[Char])] of
                                       [(_,"")] -> True
                                       _        -> False
          

          【讨论】:

            【解决方案6】:

            concat 连接多个列表,因此concat listOfStrings 将导致"f1h6b7"。 如果你只想计算正整数,你可以尝试类似

            countInts (x:xs) = if isDigit x then 1 + countInts xs else countInts xs
            

            其中(x:xs) 是一个列表模式,其头部元素为x,尾部为xs。 (所以这适用于convertedString,因为它是[Char] 的字符列表但不是,因为它实际上是[String],可以扩展为[[Char]])。

            您得到的实际输入是什么? listOfStringsconvertedString?

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2018-07-05
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多