2

有一个字符串列表 ["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 转换为一个字符串。这个算法甚至不能正常工作

你能帮我优化吗?

4

6 回答 6

5

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
于 2012-12-02T20:12:37.367 回答
2

基本原理是

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

Prelude这很容易通过一些功能解决:

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

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

isIntegerRepresentation :: String -> Bool
isIntegerRepresentation s = case reads s :: [(Integer,[Char])] of
                             [(_,"")] -> True
                             _        -> False
于 2012-12-02T20:13:39.427 回答
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]])。

你得到的实际输入是什么?listOfStrings还是convertedString

于 2012-12-02T20:12:12.653 回答
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 接受一个列表的列表,并返回一个列表,列表中的所有元素一个接一个,并且由于字符串是Chars 的列表,concat在这种情况下,需要一个列表的列表Char,并返回一个列表Char, (又名字符串)。

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

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

请注意,如果您只想查找 中的位数convertedString,您可以执行以下操作:

let listOfDigits = filter isDigit convertedString

length listOfDigits
Prelude> 3
于 2012-12-02T20:13:47.500 回答
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'].

于 2012-12-02T20:26:57.673 回答
0

Bool我发现使用以下方法转换为 0 或 1通常很有用fromEnum

import Data.Char

countInts = sum . map (fromEnum . isNumber) . concat
于 2012-12-03T07:46:30.463 回答