11

Simple problem.

Given a String, I want to be able to enter a letter and then have my function count the number of times that letter appears in a string.

countLetters :: String -> Char -> Int

How can this be done?

0

2 Answers 2

22

With

countLetters :: String -> Char -> Int
countLetters str c = length $ filter (== c) str

This gets only the characters in str that equal c, then computes the length of that.

Sign up to request clarification or add additional context in comments.

2 Comments

This suffers the performance penalty of having to traverse the entire input string once to filter, and then traverse the result of that to get the length.
But aren't length and filter both lazy functions? I would imagine that GHC could optimize a simple case like that to produce a single loop.
2

That depends on the number of calls you'd like to make to one String. Simple solution would be to just read every character in the string, if it matches the one you're looking for, increase the counter.

Now, if you're mapping over something with a counter, you can obviously use fold:

countLetters xs x = foldl (\count char -> if char == x then (count + 1) else count) 0 xs

However, if you want to do many queries, it makes more sense to build the lookup table (i.e. sort) first. Then you can get the number of repetitions of arbitrary character in O(1) (the whole algorithm is still O(n)).

2 Comments

Wouldn't your operation after sorting be more like O(m) where m is the number of repeated characters?
Assuming you're using a fixed-range fixed-size table, extraction of a value is O(1). Think raw memory access and pointer arithmetic, for example.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.