2015-12-25 1 views
0

У меня возникли проблемы при построении алгоритма для следующей задачи: учитывая учебник (this one), найдите каждый первый и последний параграфы каждого раздела.Как я могу получить первый и последний параграфы каждого раздела документа?

Получение каждого абзаца в Haskell осуществляется легко, используя split, или filter, передавая параметр новой строки, и это отлично работает. Однако для меня все сложно (я знаю только ООП). Если мы возьмем заголовки в качестве базового случая, в тексте будут две строки заголовка: одна в части индекса и одна в самом тексте. Как программа может различать их? Кроме того, как код может знать, есть ли две две строки между двумя абзацами?

Это моя попытка решить проблему;

  1. Получить каждый абзац в массив путем разбиения текста на элементы пункта

  2. Поиск индекса названий в массиве и найти второе вхождение каждого заголовка и имя, что индекс

  3. Получите параметр paragraph_array [index + 1] как первый элемент

  4. Получите paragraph_array [index-1] как последний элемент предыдущего раздела.

Я очень смущен. Любая помощь будет очень оценена.

ОБНОВЛЕНИЕ: Раздел является чем-то вроде части каждого заголовка. Например, книга исчисления может содержать 12 глав, и каждая глава может содержать 8 разделов. Нам нужно подумать, что в этой книге есть только одна глава, и у нее 4-5 разделов. Название может быть INTEGRAL, LIMIT и т. Д.

+0

'в тексте будет 2 строки заголовка'. В этом конкретном тексте строки заголовков в самом тексте всегда появляются сразу после строк новой строки. В индексе им предшествуют пробелы. – danidiaz

+0

Что такое раздел? Похож на ключевую часть вопроса, и, вероятно, первое, что нужно разбить, но вы вряд ли даже упомянете об этом в своем вопросе. –

+0

было бы более ясным, если бы вы поставили несколько небольших примеров среди вашего алгоритма, особенно абзацев, названий, разделов. –

ответ

0

Вот эскиз того, как я подхожу к этой проблеме.

Я предполагаю, что у вас есть некоторые функции, которые могут isTitle :: String -> Bool определить, является ли некоторая строка является заголовок, и что у вас есть текст раскол в список абзацев и заголовков (т.е. типа [String]).

{-# LANGUAGE RecordWildCards #-} 
module FindParagraphs where 

import Data.Maybe 

Я начинаю с типом данными с курсором из двух элементов в список, таких типа данных часто называется молнией.

data TwoZip a = 
    TwoZip { front :: [a] 
     , first :: a 
     , second :: a 
     , back :: [a] 
     } 
    deriving (Eq, Show) 

-- make a zipper from a list 
mkZip :: [a] -> Maybe (TwoZip a) 
mkZip (first:second:back) = Just (TwoZip [] first second back) 
mkZip _ = Nothing 

-- advance the zipper 
advance :: TwoZip a -> Maybe (TwoZip a) 
advance TwoZip{..} 
    | (x:xs) <- back = Just (TwoZip (first:front) second x xs) 
advance _ = Nothing 

-- and rewind our zipper (not needed in this case but nice for 
-- completeness sake) 
rewind :: TwoZip a -> Maybe (TwoZip a) 
rewind TwoZip{..} 
    | (x:xs) <- front = Just (TwoZip xs x first (second:back)) 
rewind _ = Nothing 

Чтобы найти все первые абзацы мы перебирать пунктов и выглядят на первый элемент в нашей молнии, если это название мы знаем, что следующий элемент в молнии является первым пунктом, то мы заранее!

findFirsts 
    :: (String -> Bool) --^is collection of words a title 
    -> [String] --^Titles and paragraphs 
    -> [String] --^last and first paragraphs 
findFirsts isTitle paragraphs = reverse (go (fromJust (mkZip paragraphs)) []) 
    where 
    go 
     :: TwoZip String 
     -> [String] 
     -> [String] 
    go [email protected]{..} firsts = 
     let 
     firsts' = 
      if isTitle first 
      then second:firsts 
      else firsts 
     in case advance z of 
     Nothing -> firsts' 
     Just z' -> go z' firsts' 

И тогда некоторые (упрощенный) тестовые данные:

testData = map show [1,2,3,1,3,4,1,4,3] 
isTitle = (== "1") 

first_paragraphs = findFirsts isTitle testData 

И, как мы бы хотели:

λ> first_paragraphs 
["2","3","4"] 

Вы, вероятно, может понять, как расширить это также найти последний абзац и как сделать это на одной итерации.

+0

Я не думаю, что это правильное решение для моей проблемы:/ – user3104760

+0

Прошу продумать, почему! – adamse

+0

Прежде всего, я не думаю, что это не решит проблему за отсутствие пустых строк между заголовком и абзацем, а ваш тестовый пример представляет собой массив целых чисел, и я не мог решить, как тестировать с моим файлом , И код настолько сложный и продвигается для меня, что я не хочу, чтобы это было потому, что я очень новичок в haskell и ищет более базовое и понятное решение. – user3104760

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