Haskell - найдите самое длинное слово в тексте - PullRequest
3 голосов
/ 24 сентября 2011

У меня проблема с написанием функции для поиска самого длинного слова в тексте.

Ввод: строка с большим количеством слов. Пример: "I am a young man, and I have a big house."

Результат будет 5, потому что самые длинные слова в тексте имеют 5 букв (молодые и домашние).

Я только начал изучать Хаскель. Я пробовал:

import Char
import List

maxord' (str:strs) m n = 
    if isAlpha str == True
    then maxord'(strs m+1 n)
else    if m >= n
        then maxord'(strs 0 m)
    else    maxord'(strs 0 n)

maxord (str:strs) = maxord' (str:strs) 0 0

Я хочу вернуть n как результат, но я не знаю, как это сделать, и, похоже, что-то не так с кодом

Любая помощь? Спасибо

Ответы [ 3 ]

13 голосов
/ 24 сентября 2011

Попробуйте разбить свою задачу на несколько подзадач.Я бы предложил разделить его следующим образом:

  1. Превратить строку в список слов.Например, ваш пример строки становится

    ["I","am","a","young","man","and","I","have","a","big","house"]
    
  2. map length над списком.Это вычисляет длину слова.Например, список на шаге 1 становится

    [1,2,1,5,3,3,1,4,1,3,5]
    
  3. Найти слово с наибольшим количеством символов.Для этого вы можете использовать maximum.

Вы можете составить эти шаги, используя оператор (.), который объединяет две функции вместе.Например, если функция для выполнения шага 1 называется toWords, вы можете выполнить всю задачу в одной строке:

maxord = maximum . map length . toWords

Реализация toWords оставлена ​​в качестве упражнения для читателя.Если вам нужна помощь, напишите комментарий.

4 голосов
/ 24 сентября 2011

Здесь есть несколько проблем.Давайте начнем с синтаксиса.

Ваши else части должны иметь отступ , равный или больше if, к которому они относятся , например, вот так:

if ...
then ...
else if ...
     then ...
     else ...

Далее ваши функции приложения.В отличие от многих других языков, в Haskell круглые скобки используются только для группировки и кортежей .Поскольку применение функций в Haskell очень распространено, мы используем для этого максимально упрощенный синтаксис, а именно пробелы.Чтобы применить функцию maxord' к аргументам strs, m+1 и n, мы пишем maxord' strs (m+1) n.Обратите внимание, что поскольку приложение-функция имеет наивысший приоритет, мы должны добавить круглые скобки вокруг m+1, иначе это будет интерпретировано как (maxord' strs m) + (1 n).

Вот и все для синтаксиса.Следующая проблема является семантической, а именно, что у вас есть рекурсия без базового случая .Используя шаблон (str:strs), вы указали, что делать, когда у вас осталось несколько символов, но вы не указали, что делать, когда достигнете конца строки.В этом случае мы хотим вернуть n, поэтому мы добавляем регистр для этого.

maxord' [] m n = n

Фиксированный maxord', таким образом,

maxord' [] m n = n
maxord' (str:strs) m n = 
    if isAlpha str == True
    then maxord' strs (m+1) n
    else if m >= n
         then maxord' strs 0 m
         else maxord' strs 0 n

Однако,Обратите внимание, что это решение не очень идиоматично.Он использует явную рекурсию, if выражения вместо охранников, сравнивая булевы значения с True и имеет очень императивный вид.Более идиоматическим решением было бы что-то вроде этого.

maxord = maximum . map length . words

Это простая цепочка функций, где words разбивает ввод в список слов, map length заменяет каждое слово его длиной, иmaximum возвращает максимум из этих длин.

Хотя обратите внимание, что это не то же самое, что ваш код, так как функция words использует несколько другие критерии при разбиении ввода.

2 голосов
/ 24 сентября 2011

Есть пара проблем

Нет конца для вашей рекурсии. Вы хотите вернуть n при обработке всего ввода.

maxord' [] _ n = n

Синтаксис:

maxord'(strs 0 m)

это означает, что вызов применяется strs с параметрами 0 и m, а затем используется в качестве аргумента для maxord. То, что вы не хотите делать, это:

maxord' strs 0 m

m+1 должно быть (m+1).

Возможно, вы захотите обработать пустые строки, но maxord не позволяет этого.

maxord s = maxord' s 0 0

Это должно сделать это. Есть пара тонкостей. maxord' не должно попадать в пространство имен, используйте where. (max m n) намного более лаконичен, чем если бы вы использовали. И проверьте другие ответы, чтобы увидеть, как вы можете построить свое решение, соединив встроенные вещи вместе. Рекурсии намного сложнее читать.

...