2012-12-02 74 views
0

有一个String [“f”,“1”,“h”,“6”,“b”,“7”]的列表。如何计算字符串列表中的整数。 Haskell

我该如何计算这个列表中的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转换为一个字符串。这个算法甚至不能正常工作

你能帮我优化吗?

+2

你要算在列表中的'String's是整数的表示,做我理解正确吗?只有非负整数还是负数? –

+0

是的。我想要统计整数表示的字符串。对于'Data.Char(isNumber)',它们可能是否定的 – SEMA

回答

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 
0

concat连接多个列表,所以concat listOfStrings将导致"f1h6b7"。 如果您只想计算正整数,你可以尝试沿着

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

线,其中(x:xs)是头元素xxs尾巴的列表模式的东西。 (因此,这会为convertedString工作,因为它是一个字符[Char]listOfStrings因为它实际上是[String]可扩展到[[Char]]的列表)。

你有什么实际的输入? listOfStringsconvertedString

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 
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 s的列表,因此concat在此列表中列出了Char列表,并返回一个列表单个列表Char,(又名一个字符串)。

该过滤器使用\x -> isDigit x简化为isDigit。这是完全一样的功能。

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

注意数字,如果你只是想找到的convertedString数字的号码,你可以这样做:

let listOfDigits = filter isDigit convertedString 

length listOfDigits 
Prelude> 3 
0

我相信最好的答案你会

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

在这里,我们检查,如果一个字符是数字,并指望他们

Ps。这将适用于['f', '1', 'h', '6', 'b', '7']

+1

+1,对于'foldl''邪恶的可能是-1 –

0

我发现它经常有用Bool转换0或1使用fromEnum到:(?以10为基数)

import Data.Char 

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