#haskell #count #counting
Вопрос:
Реализуйте
countA :: [Char] -> Int
функцию, которая подсчитывает количество вхождений символовa
иA
в строке.
Подсказка: Является ли элемент
a
A
или какой-либо другой элемент, можно проверить с помощью сопоставления с образцом.
Например:
countA "Appleapplet" == 2
countA "Nietzsche" == 0
Я новичок в изучении Хаскелла, и первое, что пришло мне в голову, — это сделать if
then
else
утверждение, но это не может быть ответом, потому что я должен делать это с помощью сопоставления шаблонов. Я даже не знаю, с чего начать, и я не до конца понимаю, как работает сопоставление шаблонов в списках. Я не могу использовать какие-либо импортированные функции в этом упражнении.
Комментарии:
1. Ответ
if
…then
else
определенно может быть частью ответа.
Ответ №1:
Вы можете использовать if
— then
else
, чтобы проверить, является ли первый символ списка 'a'
или 'A'
, хотя сопоставление шаблонов может быть более элегантным.
Что вам нужно, так это рекурсивная функция с пустым списком (1) в качестве базового случая, в этом случае общее количество раз, когда это a
происходит или A
происходит 0
. В рекурсивном случае мы работаем с непустым списком с x
первым символом и xs
(возможно, пустым) хвостом списка. В этом случае мы можем проверить, равен ли первый символ x
'a'
или 'A'
, и в этом случае увеличить результат рекурсивного вызова. Таким образом, мы можем реализовать это как:
countA :: String -> Int
countA [] = … -- (1)
contaA (x:xs) = if x == 'a' || x == 'A' then … else … -- (2)
где вам все еще нужно заполнить …
детали. Тем, кто находится во втором случае (2) , потребуется выполнить рекурсивные вызовы.
Комментарии:
1. Попробовал ваш ответ, и он работает, но мне также любопытно, как это будет выглядеть при сопоставлении шаблонов. Вы можете мне сказать?
2. @AWheelbarrow: вместо
contaA (x:xs) = if x == 'a' || x == 'A' then … else …
вас используйте три строки:contaA ('a':xs) = ...
,contaA ('A':xs) = ...
иcontaA (x:xs) = ...
. Последний случай будет соответствовать только в том случае, если сопоставление шаблонов для('a': xs)
и('A': xs)
завершится неудачно.3. И что мне нужно написать вместо …-ов? Если я попытаюсь
countA ('a':xs) = countA('A':xs) countA(xs)
countA ('A':xs) = countA('a':xs) countA(xs)
,countA (x:xs) = 0
моя программа зависнет и ничего не распечатает.4. @AWheelbarrow: вы должны сделать рекурсивный вызов на хвосте
xs
, а не на голове. Для некоторых предложений , которые вы должны добавить1
,countA (x:xs)
следует также выполнить рекурсивный вызов.5. таким образом, первые два из этих предложений должны работать с рекурсией в конце списка и добавлять одно к результату рекурсии, последнее должно повторяться только в конце списка.