Vyřešeno: najděte pozici podřetězce v řetězci

Dobře, pojďme začít s tím, jak najít podřetězec v řetězci v Haskell.

Haskell je čistě funkcionální programovací jazyk známý svou vysokou úrovní abstrakce a expresivní syntaxe. Jedním z běžných úkolů při práci s řetězci je najít podřetězec ve větším řetězci – to znamená identifikovat přesnou pozici, kde se vyskytuje určitá sekvence znaků.

Pro tento účel můžeme využít dvě vestavěné funkce Haskell: `isPrefixOf` a `tails`. `isPrefixOf` kontroluje, zda je seznam prefixem jiného seznamu, a `tails` generuje všechny koncové části seznamu. K získání indexu prvního výskytu konkrétního prvku použijeme také funkci `elemIndex` z `Data.List`.

Zde je jednoduché řešení problému:

import Data.List

findSubstring :: String -> String -> Maybe Int
findSubstring substr str = 
    elemIndex True $ map (isPrefixOf substr) (tails str)

Fungování Kodexu

Funkce `findSubstring` přebírá dva argumenty, `substr` a `str`, které reprezentují podřetězec, který hledáme, respektive řetězec, ve kterém hledáme.

  • Za prvé, `tails str` generuje všechny možné konce řetězce `str`. Například zadaný řetězec „ahoj“, „ocasy“ vygenerují [“ahoj“, „ahoj“, „llo“, „lo“, „o“, „“].
  • Dále `map (isPrefixOf substr)` aplikuje funkci `isPrefixOf substr` na každý prvek seznamu vytvořeného `tails str`. Získáte tak seznam booleovských hodnot, z nichž každá označuje, zda je `substr` prefixem odpovídajícího prvku v původním seznamu.
  • Nakonec `elemIndex True` hledá v tomto seznamu booleanů první výskyt `True`, který odpovídá pozici `substr` v `str`, a vrací jej zabalený v datovém typu `Možná`.

Klíčové funkce a knihovny

Data.List je knihovna Haskell nabitá užitečnými funkcemi pro manipulaci se seznamy. Mimo jiné exportuje funkce `isPrefixOf`, `tails` a `elemIndex`, které jsme použili v našem řešení.

Funkce `isPrefixOf` je pro naše řešení obzvláště klíčová. Kontrolou, zda je náš cílový podřetězec prefixem každého dílčího seznamu, v podstatě zkontroluje každou možnou počáteční pozici našeho podřetězce v rámci původního řetězce.

Extrapolace a varianty

Tento jednoduchý přístup lze extrapolovat pro provádění složitějších úkolů, jako je vyhledání všech výskytů podřetězce, nahrazení podřetězce jiným řetězcem nebo rozdělení řetězce na části na základě oddělovače.

Chcete-li například nahradit všechny výskyty podřetězce, můžete použít `intercalate` z Data.List ke spojení částí získaných přerušením původního řetězce na pozicích cílového podřetězce.

Navzdory své inherentní jednoduchosti a expresivitě Haskellův přístup ke zpracování řetězců ukazuje sílu funkcionálního programování při řešení běžných úloh čistým, čitelným a stručným způsobem.

Související příspěvky:

Zanechat komentář