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 を 1 つの文字列に変換することはできません。このアルゴリズムは正しく動作しません

最適化を手伝ってもらえますか?

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

Stringあとは、aが整数の表現かどうかを判断するための適切な式を見つけるだけです。Prelude独自のテストを作成することもできますが、そのために関数を再利用することもできます。

isIntegerRepresentation :: String -> Bool
isIntegerRepresentation s = case reads s :: [(Integer,[Char])] of
                             [(_,"")] -> True
                             _        -> False
于 2012-12-02T20:13:39.427 に答える
0

Boolを使用して0または1に変換すると便利なことがよくあります。fromEnum

import Data.Char

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

concat複数のリストを連結するconcat listOfStringsため、結果は"f1h6b7". 正の整数のみを数えたい場合は、次のように何かを試すことができます

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

whereは、head 要素と tail を(x:xs)持つリストのパターンです。(したがって、これは文字のリストであるため機能しますが、実際には に展開できるため機能しません)。xxsconvertedString[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 はリストのリストを取得し、リストのすべての要素を交互に並べた単一のリストを返します。文字列は のリストであるためCharconcatこの場合は のリストのリストを取得しChar、の単一のリストを返します。Char、(別名文字列)。

\x -> isDigit xフィルタは、 を使用することから単純化されてい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 が数値かどうかを確認し、それらをカウントします

Ps。これは['f', '1', 'h', '6', 'b', '7'].

于 2012-12-02T20:26:57.673 に答える