Reputation: 1241
i have a string something like that
test = "fDfDfadsptupauOasufDfDfadsptupausapasdfogfdifdsudsaufuffxDfDfDfDfDfDfadsptupauOasufDfDfadsptupausap"
and i would like to get the number of the occurrence for example of the char '0' with respect to the char coming after the '0' , so for example for the string test when i call my function it should give
('0',[(8,'w'),(2,'q')])
which means that char '0' occurs 8 times in the form "0w" and 2 times in the form "2q"
until now i manged to the total occurrence of '0' which is 10 but i cannot get it with respect to its neighbor , my code
freq c l = filter (==c) l
function::[(Char ,Int)]
function = [('0' , sum (map length (map (freq '0') test)))]
note my output should be of the type
function :: [(Char,[(Int,Char)])
Upvotes: 0
Views: 343
Reputation: 54058
Think about how you can transform your data, a String
into something that can be processed to give you the result you want. What you're really interested in is pairs of adjacent characters, so your first step would be to write a function which pairs each element with its successor:
matchSuccessors :: String -> [(Char, Char)]
matchSuccessors text = undefined
Then you want to group these together by what the first element is, such as '0'
. For this you'll want to look at sort/sortBy
and group/groupBy
in Data.List
:
organizeSuccessors :: [(Char, Char)] -> [[(Char, Char)]]
organizeSuccessors succs = undefined
At this point you should have something like
> organizeSuccessors (matchSuccessors "abababacacabac")
[[('a','b'),('a','b'),('a','b'),('a','b')],
[('a','c'),('a','c'),('a','c')],
[('b','a'),('b','a'),('b','a'),('b','a')],
[('c','a'),('c','a')]
]
(whitespace added for readability)
Now you can very easily measure the length of each, pairing that with what element it was:
countSuccessorGroups :: [[(Char, Char)]] -> [((Char, Char), Int)]
countSuccessorGroups grps = map (\grp -> (head grp, length grp)) grps
So now you would see
> countSuccessorGroups $ organizeSuccessors $ matchSuccessors "abababacacabac"
[(('a', 'b'), 4),
(('a', 'c'), 3),
(('b', 'a'), 4),
(('c', 'a'), 2)
]
Now armed with your knowledge of sortBy
and groupBy
you should be able to convert this into what you need:
organizeByFirstLetter :: [((Char, Char), Int)] -> [(Char, [(Int, Char)])]
organizeByFirstLetter succgrps = undefined
So your entire program would be
function
= organizeByFirstLetter
$ countSuccessorGroups
$ organizeSuccessors
$ matchSuccessors
$ test
You can also break up organizeByFirstLetter
into multiple steps as necessary.
Upvotes: 4