Halawa
Halawa

Reputation: 1241

occurrence of char with respect to its neighbor in haskell

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

Answers (1)

bheklilr
bheklilr

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

Related Questions