2016-11-05 3 views
-5

Я пытаюсь написать функцию, которая примет String и Char и выводит индексы, где символ встречается в строке.Как найти вхождения символов во входной строке в Haskell

stringCount str ch = 
Input : "haskell is hard" `h` 
Output:[0,11] 
Input : "haskell is hard" `a` 
Output:[1,12] 

Пожалуйста, помогите мне Я изо всех сил пытаюсь понять Хаскелла.

ответ

1

Существует много способов сделать это, но поскольку вы упоминаете, что вы новичок в Haskell, понимание списка может быть проще всего понять (я предполагаю, что это домашнее задание, поэтому вы должны реализовать его самостоятельно, а не использовать elemIndices):

stringCount str ch = [ y | (x, y) <- zip str [0..], x == ch ] 
stringCount "haskell is hard" 'a' 
-- [1,12] 
stringCount "haskell is hard" 'h' 
-- [0,11] 

Здесь мы zip строка str с бесконечным списком, начиная с 0, производя кортежи ('h', 0), ('a', 1), ('s', 2) и т.д. затем мы выбираем только кортежи, где символ (связанный с x) равен аргумент ch и вернуть индекс (привязанный к y) для каждого из них.

Если вы хотите сохранить текущий порядок аргументов, но использовать elementIndices вы можете использовать следующее:

stringCount' = flip elemIndices 
stringCount' "haskell is hard" 'h' 
-- [0,11] 
+0

Большое спасибо Michael Kohl и как я могу сделать это с elemIndex? – Diana

+0

Извините, это 'elemIndices', а не' elemIndex' (последний дает вам только индекс первого вхождения). 'elemIndices 'a' 'haskell is hard'' дает желаемый результат, поэтому вам просто нужно перевернуть порядок аргументов. –

0

вы можете использовать elemIndex ходить по списку, или просто написать свой собственный

indexOf x = map fst . filter (\(_,s) -> s==x) . zip [0..] 

indexOf 'a' "haskell is hard" 
[1,12] 

или с findIndices

import Data.List(findIndices) 
findIndices (\x -> x=='a') "haskell is hard" 
[1,12] 
0

Вот более простой, но менее сложные решения, что один пост по karakfa :

stringCount :: String -> Char -> Integer -> [Integer] 
stringCount [] c _ = [] 
stringCount (x:xs) c pos | x == c = pos:(stringCount xs c (pos+1)) 
         | otherwise = stringCount xs c (pos+1) 

Идея в том, что вы идете через строковый символ char с помощью рекурсии, а затем сравните фактический символ (голова в данный момент) с символом, переданным как аргумент. Чтобы отслеживать позицию, я использую счетчик pos и увеличиваю его для каждого вызова рекурсии.

+0

Большое спасибо dreamcrash – Diana

Смежные вопросы