如何计算字符串列表中的整数。哈斯克尔

时间:2012-12-02 19:53:39

标签: string list haskell

有一个字符串[“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转换为一个字符串。该算法甚至无法正常工作

你能帮我优化吗?

6 个答案:

答案 0 :(得分:4)

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

答案 1 :(得分:2)

基本原则是

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

这很容易通过一些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

答案 2 :(得分:0)

concat连接多个列表,因此concat listOfStrings会产生"f1h6b7"。 如果你只想计算正整数,你可以尝试一些

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

其中(x:xs)是包含头元素x和尾部xs的列表的模式。 (因此,这适用于convertedString,因为它是[Char] 的字符列表,但listOfStrings不是,因为它实际上是[String]扩展到[[Char]])。

您获得的实际输入是多少? listOfStringsconvertedString

答案 3 :(得分:0)

您的代码可以重写为:

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获取一个列表列表,并返回一个列表,列表中的所有元素彼此相继,并且由于字符串是Char的列表,concat在这种情况下需要一个列表列表Char,并返回Char的单个列表,(也称为字符串)。

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

我使用digitToInt代替\x -> read [x] :: Int

来阅读数字

请注意,如果您只想查找convertedString中的位数,您可以这样做:

let listOfDigits = filter isDigit convertedString

length listOfDigits
Prelude> 3

答案 4 :(得分:0)

我确定你的最佳答案是

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']

答案 5 :(得分:0)

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

import Data.Char

countInts = sum . map (fromEnum . isNumber) . concat
相关问题