2012-12-02 150 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 
相關問題