Форум программистов, компьютерный форум, киберфорум
Haskell
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.88/26: Рейтинг темы: голосов - 26, средняя оценка - 4.88
0 / 0 / 0
Регистрация: 14.02.2012
Сообщений: 8

Получить из списка - список списков

21.08.2012, 14:08. Показов 5016. Ответов 16
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем добрый день. Подскажите пожалуйста мне необходимо реализовать следующее:
на входе строка вида "папа#мама#брат1#брат2#сестра"
а получить надо ["папа","мама","брат1","брат2","сестр а"]

я только начинаю разбираться с хаскелом (во имя добра ) все до чего сумел додумать это выделять первое слово до знака #.
Haskell
1
2
3
4
5
6
7
q = "papa#mama"
 
tt' :: Int -> Int -> String -> String
tt' _ _ []    = []
tt' m k (x:s) | m>0 = tt' 0 0 (drop m (x:s)) 
              | x=='#' = []
              | x/='#' = x : tt' 0 (k+1) s
Лишние входные параметры (Int -> Int) это я пытался как то реализовать чтобы функция запоминала на какой позиции списка я остановился прошлый раз. Не могу придумать алгоритм чтобы реализовать. Помогите пожалуйста.

ps. в перспективе наверно надо будет сделать из строки список списков списков ... чтото вроде
вход: "red#blue#yellow##water#fire#"
выход: [ ["red","blue","yellow"],["water","fire"] ]
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
21.08.2012, 14:08
Ответы с готовыми решениями:

Получить список списков и вернуть список из N-х элементов подсписков
Доброго времени суток! пожалуйста помогите с функциональным программированием! ^_^ Условие задачи: напишите функцию ] -> Int...

Вернуть список элементов типа Bool (из подаваемого на вход списка списков)
Добрый день. Нужно написать ф-ю, возвращающую список элементов типа Bool. На вход подаём список списков. Работу функции продемонстрирую...

Функция, принимающая два списка, и возвращающая список из произведений элементов общих списков
функция которая принимает два списка, и возвращает список из произведений элементов общих списков

16
17 / 7 / 0
Регистрация: 20.08.2012
Сообщений: 51
21.08.2012, 14:26
Haskell
1
2
3
4
5
stringList string = buildList string '' []
 
buildList string@(sym:syms) word list = | string == [] = list
                                     | sym == '#' = buildList syms '' (list ++ word)
                                     | otherwise = buildList syms (word ++ sym) list
0
0 / 0 / 0
Регистрация: 14.02.2012
Сообщений: 8
21.08.2012, 14:36  [ТС]
Цитата Сообщение от flammberg Посмотреть сообщение
Haskell
1
2
3
4
5
stringList string = buildList string '' []
 
buildList string@(sym:syms) word list = | string == [] = list
                                     | sym == '#' = buildList syms '' (list ++ word)
                                     | otherwise = buildList syms (word ++ sym) list
попытался запустить этот код, на что компилятор мне сказал:

test.hs:1:39:
lexical error in string/character literal at character '\''
Failed, modules loaded: none.
0
17 / 7 / 0
Регистрация: 20.08.2012
Сообщений: 51
21.08.2012, 14:41
Вообще, я тоже новичок в Хаскеле. Если ошибка в первой строке, то возможно, компилятору не нравится использование string в качестве идентификатора.
0
Супер-модератор
Эксперт функциональных языков программированияЭксперт Python
 Аватар для Catstail
38168 / 21103 / 4307
Регистрация: 12.02.2012
Сообщений: 34,692
Записей в блоге: 14
21.08.2012, 14:43
Вот длинноватое, но работающее решение:

Haskell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
-- позиция символа с в строке x
 
indStr :: Char -> String -> Int
indStr c ini@(x:xs) = if (c `elem` ini) then 
                          if (c == x) then 1
                          else 1 + (indStr c xs)
                      else
                          0
 
strList :: String -> [String]
strList []=[]
strList x = if ix == 0 then [x]
            else (take (ix-1) x) : strList (drop ix x)
            where ix=(indStr '#' x)
 
Main> strList "qwe#yyy#iii#"
 
["qwe","yyy","iii"]
1
0 / 0 / 0
Регистрация: 14.02.2012
Сообщений: 8
21.08.2012, 14:54  [ТС]
Цитата Сообщение от Catstail Посмотреть сообщение
Вот длинноватое, но работающее решение:

Haskell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
-- позиция символа с в строке x
 
indStr :: Char -> String -> Int
indStr c ini@(x:xs) = if (c `elem` ini) then 
                          if (c == x) then 1
                          else 1 + (indStr c xs)
                      else
                          0
 
strList :: String -> [String]
strList []=[]
strList x = if ix == 0 then [x]
            else (take (ix-1) x) : strList (drop ix x)
            where ix=(indStr '#' x)
 
Main> strList "qwe#yyy#iii#"
 
["qwe","yyy","iii"]
спасибо, вроде работает =) попробую щас разобраться как оно работает
0
 Аватар для Сtrl
144 / 134 / 8
Регистрация: 19.07.2011
Сообщений: 184
21.08.2012, 15:35
Правильное решение:
Haskell
1
2
3
4
5
6
import Data.List (break)
 
f :: String -> [String]
f xs =
    let (a, b) = break (=='#') xs in
    a : if null b then [] else f (tail b)
Добавлено через 18 минут
Цитата Сообщение от acrost Посмотреть сообщение
ps. в перспективе наверно надо будет сделать из строки список списков списков ... чтото вроде
вход: "red#blue#yellow##water#fire#"
выход: [ ["red","blue","yellow"],["water","fire"] ]
Прошу прощения, сразу не заметил. Вот более общее решение:
Haskell
1
2
3
4
5
6
7
8
9
import Data.List (break)
 
g :: Eq a => a -> [a] -> [[a]]
g c xs =
    let (a, b) = break (==c) xs in
    a : if null b then [] else g c (tail b)
 
f :: String -> [[String]]
f = g "" . g '#'
Пример работы:
Haskell
1
2
Main> f "water#ice#fire##red#green#blue"
[["water","ice","fire"],["red","green","blue"]]
2
0 / 0 / 0
Регистрация: 14.02.2012
Сообщений: 8
21.08.2012, 15:41  [ТС]
Цитата Сообщение от Сtrl Посмотреть сообщение
Правильное решение:
Пример работы:
Haskell
1
2
Main> f "water#ice#fire##red#green#blue"
[["water","ice","fire"],["red","green","blue"]]
большое спасибо =)
сам я нескоро бы это реализовал.
0
Супер-модератор
Эксперт функциональных языков программированияЭксперт Python
 Аватар для Catstail
38168 / 21103 / 4307
Регистрация: 12.02.2012
Сообщений: 34,692
Записей в блоге: 14
21.08.2012, 18:55
Цитата Сообщение от Сtrl Посмотреть сообщение
Правильное решение:
- а вот еще одно правильное (и, как мне кажется) более простое решение:

Haskell
1
2
3
4
5
6
7
8
9
10
convStr :: String -> String -> [String]
 
convStr [] _ = []
convStr (x:xs) y = if (x == '#') then y : convStr xs []
                                 else convStr xs (y ++ [x])
 
 
Main> convStr "qqq#uuu#bbb#" []
 
["qqq","uuu","bbb"]
Добавлено через 55 минут
Поправочка:

Haskell
1
2
3
4
5
6
7
8
9
10
convStr :: String -> String -> [String]
 
convStr [] y = [y]  -- чтобы корректно обрабатывать случай, когда в конце строки нет #
convStr (x:xs) y = if (x == '#') then y : convStr xs []
                                 else convStr xs (y ++ [x])
 
 
Main> convStr "qqq#uuu#bbb#" []
 
["qqq","uuu","bbb"]
1
 Аватар для Сtrl
144 / 134 / 8
Регистрация: 19.07.2011
Сообщений: 184
21.08.2012, 19:08
Цитата Сообщение от Catstail Посмотреть сообщение
- а вот еще одно правильное (и, как мне кажется) более простое решение
Поправочка
Да, действительно проще. Правда вот пара оптимизаций:
Haskell
1
2
3
4
5
6
7
8
9
10
convStrR :: String -> String -> [String]
convStrR y [] = [y]
convStrR y (x:xs) =
    if (x == '#')
    then y : convStrR [] xs
    else convStrR (x:y) xs
    
 
convStr :: String -> [String]
convStr = map reverse . convStrR []
0
Супер-модератор
Эксперт функциональных языков программированияЭксперт Python
 Аватар для Catstail
38168 / 21103 / 4307
Регистрация: 12.02.2012
Сообщений: 34,692
Записей в блоге: 14
21.08.2012, 19:12
Решение усложненной задачи получается более громоздким:

Haskell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
convStr :: String -> String -> [String]
convStr [] y = [y]
convStr (x:xs) y = if (x == '#') then y : convStr xs []
                                 else convStr xs (y ++ [x])
 
convStr2 :: String -> String -> [String]
convStr2 [] y = [y]
convStr2 (x:xs) z = if (x == '#') && (take 1 xs == "#") then  z : convStr2 (drop 1 xs) []
                                                        else convStr2 xs (z ++ [x])  
 
f :: String -> [String]
f x = convStr x []
 
task :: String -> [[String]]
task x = map f (convStr2 x [])
 
Main> task "aaa#bbb##ccc#ddd##eee"
[["aaa","bbb"],["ccc","ddd"],["eee"]]
Добавлено через 2 минуты
Цитата Сообщение от Сtrl Посмотреть сообщение
Да, действительно проще.
- но для усложненной задачи, Ваш код, конечно, лучше...
0
 Аватар для Сtrl
144 / 134 / 8
Регистрация: 19.07.2011
Сообщений: 184
21.08.2012, 19:22
Цитата Сообщение от Catstail Посмотреть сообщение
но для усложненной задачи, Ваш код, конечно, лучше...
Не факт, кстати. Вот решение на основе вашего алгоритма:
Haskell
1
2
3
4
5
6
7
8
9
convListR :: Eq a => a -> [a] -> [a] -> [[a]]
convListR c y [] = [y]
convListR c y (x:xs) =
    if (x == c)
    then y : convListR c [] xs
    else convListR c (x:y) xs
 
convStr :: String -> [[String]]
convStr = convListR [] [] . map reverse . convListR '#' []
Тоже 9 строк. Правда приходится использовать reverse, а это плохо для производительности. (Многократное использование ++ еще хуже, поэтому я отказался от него в пользу reverse).
1
 Аватар для calabi-yau
78 / 64 / 5
Регистрация: 25.03.2012
Сообщений: 71
21.08.2012, 19:38
Лучший ответ Сообщение было отмечено как решение

Решение

Цитата Сообщение от acrost Посмотреть сообщение
ps. в перспективе наверно надо будет сделать из строки список списков списков ... чтото вроде
вход: "red#blue#yellow##water#fire#"
выход: [ ["red","blue","yellow"],["water","fire"] ]

Haskell
1
2
3
4
5
6
7
import Text.ParserCombinators.ReadP
 
test = foldr (const . fst) [] . readP_to_S read_p
  where
    read_p = do xs <- sepBy (sepBy (many get) $ char '#') $ string "##"
                eof
                return xs
Code
1
2
3
4
5
*Main> test "red#blue#yellow#water#fire"
[["red","blue","yellow","water","fire"]]
*Main> 
*Main> test "red#blue#yellow##water#fire"
[["red","blue","yellow"],["water","fire"]]
3
Эксперт С++
 Аватар для Nameless One
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
22.08.2012, 02:51
Haskell
1
2
3
4
5
6
7
8
{-# LANGUAGE OverloadedStrings #-}
 
import Data.Text (split, Text (..))
import Data.List (groupBy)
import Data.Functor ((<$>))
 
groupWords :: Text -> [[Text]]
groupWords = filter (not . null) . map (filter (/= "")) <$> groupBy (const (/= "")) . split (== '#')
Haskell
1
2
3
4
5
6
7
8
*Main> :set -XOverloadedStrings
*Main> groupWords "red#blue#green#water#fire"
[["red","blue","green","water","fire"]]
*Main> groupWords "red#blue#green#water#fire#" -- trailing '#'
[["red","blue","green","water","fire"]]
*Main> groupWords "red#blue#green##water#fire#" -- groups separator
[["red","blue","green"],["water","fire"]]
*Main>
2
Эксперт С++
 Аватар для Nameless One
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
22.08.2012, 03:10
Лучший ответ Сообщение было отмечено как решение

Решение

Еще вариант, требует установленного пакета split (описание пакета забавное)
Haskell
1
2
3
4
import Data.List.Split
 
groupWords :: String -> [[String]]
groupWords = map (wordsBy (== '#')) . splitOn "##"
Haskell
1
2
*Main> groupWords "red#green#blue##water#fire#"
[["red","green","blue"],["water","fire"]]
3
Супер-модератор
Эксперт функциональных языков программированияЭксперт Python
 Аватар для Catstail
38168 / 21103 / 4307
Регистрация: 12.02.2012
Сообщений: 34,692
Записей в блоге: 14
22.08.2012, 10:08
Цитата Сообщение от Nameless One Посмотреть сообщение
требует установленного пакета
- если найти пакет, в котором для решения этой задачи есть специальная функция, скажем f, то решение будет совсем коротким
0
22.08.2012, 10:09

Не по теме:

Цитата Сообщение от Catstail Посмотреть сообщение
- если найти пакет, в котором для решения этой задачи есть специальная функция, скажем f, то решение будет совсем коротким
где б его еще найти...

1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
22.08.2012, 10:09
Помогаю со студенческими работами здесь

Написать программу, которая получает список из списков из списков чисел
Всем привет, мне нужно написать программу, которая получает список из списков из списков чисел, ,],,],,]] примерно так , и потом...

Как из списка кортежей получить список?
-&gt; ... Добавлено через 58 минут convert :: ( -&gt; Верно определены типы? Добавлено через 13 минут let spisok = (1,2) (snd...

Как получить элемент списка вложенного в список?
Как из списка ,] Достать 4?

Задан список. Сформировать список списков
Задан список . Сформировать список списков ,, , ,..., . Добавлено через 6 часов 5 минут reshenie :: -&gt; reshenie = ...

Получение списка списков
Здравствуйте! Я хочу получить список списков длины исходного, начинающийся с каждого его элемента, например g= - исходный список ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
Новые блоги и статьи
Воспроизведение звукового файла с помощью SDL3_mixer при касании экрана Android
8Observer8 26.01.2026
Содержание блога SDL3_mixer - это библиотека я для воспроизведения аудио. В отличие от инструкции по добавлению текста код по проигрыванию звука уже содержится в шаблоне примера. Нужно только. . .
Установка Android SDK, NDK, JDK, CMake и т.д.
8Observer8 25.01.2026
Содержание блога Перейдите по ссылке: https:/ / developer. android. com/ studio и в самом низу страницы кликните по архиву "commandlinetools-win-xxxxxx_latest. zip" Извлеките архив и вы увидите. . .
Вывод текста со шрифтом TTF на Android с помощью библиотеки SDL3_ttf
8Observer8 25.01.2026
Содержание блога Если у вас не установлены Android SDK, NDK, JDK, и т. д. то сделайте это по следующей инструкции: Установка Android SDK, NDK, JDK, CMake и т. д. Сборка примера Скачайте. . .
Использование SDL3-callbacks вместо функции main() на Android, Desktop и WebAssembly
8Observer8 24.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
моя боль
iceja 24.01.2026
Выложила интерполяцию кубическими сплайнами www. iceja. net REST сервисы временно не работают, только через Web. Написала за 56 рабочих часов этот сайт с нуля. При помощи perplexity. ai PRO , при. . .
Модель сукцессии микоризы
anaschu 24.01.2026
Решили писать научную статью с неким РОманом
http://iceja.net/ математические сервисы
iceja 20.01.2026
Обновила свой сайт http:/ / iceja. net/ , приделала Fast Fourier Transform экстраполяцию сигналов. Однако предсказывает далеко не каждый сигнал (см ограничения http:/ / iceja. net/ fourier/ docs ). Также. . .
http://iceja.net/ сервер решения полиномов
iceja 18.01.2026
Выкатила http:/ / iceja. net/ сервер решения полиномов (находит действительные корни полиномов методом Штурма). На сайте документация по API, но скажу прямо VPS слабенький и 200 000 полиномов. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru