Форум программистов, компьютерный форум, киберфорум
Haskell
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.73/11: Рейтинг темы: голосов - 11, средняя оценка - 4.73
Модератор
Эксперт функциональных языков программирования
3142 / 2290 / 469
Регистрация: 26.03.2015
Сообщений: 8,920

Подпоследовательности с одинаковыми суммами

31.05.2015, 02:40. Показов 2603. Ответов 26
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Условие задачи:
Есть N разных положительных целых чисел.
Требуется найти все пары последовательностей из этих чисел длинной не более M, такие что они будут иметь одинаковую сумму.

Решение:
Haskell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
data NodeList = NodeList 
    { nlRoot  :: [Int]
    , nlLength :: Int
    , nlSum    :: Int }
    deriving (Show)
 
makeSums :: [Int] -> Int -> [NodeList] -> [NodeList]
makeSums [] _  acc         = acc    
makeSums (x:xs) maxlen acc = makeSums xs maxlen $ addNodeList $ (++) acc $ map addNode $ filter lessLen acc
    where addNodeList y = (NodeList [x] 1 x) : y
          addNode (NodeList root len sum) = NodeList (x:root) (len+1) (sum+x) 
          lessLen y = nlLength y < maxlen
 
makePairs :: [NodeList] -> [([Int], [Int])] -> [([Int], [Int])]
makePairs [] acc     = acc
makePairs (x:xs) acc = makePairs xs $ (++) acc $ map pairNodes $ filter sameSum xs 
    where sameSum y = nlSum x == (nlSum y)
          pairNodes y = (nlRoot x, nlRoot y)
 
solve :: [Int] -> Int -> [([Int], [Int])]
solve nums maxlen = makePairs (makeSums nums maxlen []) []
    
main = do 
  print $ solve [1,2,3,4] 3
Вопросы:
1. Какие есть способы избежать конфликта имён в строках 2-4 с именами функций из текущего контекста?
2. Как лучше всего "упаковать" makeSums и makePairs во внутрь функции solve?
3. Как можно упростить и/или ускорить этот код (кроме использования хэш-таблицы в makePairs)?

Добавлено через 26 минут
4. Какой есть хороший способ засекать время выполнения функции?

Добавлено через 32 минуты
Haskell: Успешно time: 3.77 memory: 7624 signal:0
C#: Успешно time: 0.13 memory: 24264 signal:0
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
31.05.2015, 02:40
Ответы с готовыми решениями:

Номера строк с одинаковыми суммами
Здравствуйте! Подскажите, пожалуйста, код для выведения номеров всех строк с одинаковыми суммами и их суммы (в матрице). Например, дана...

Разбиение множества на подмножества с одинаковыми суммами
Здраствуйте. Есть такая задача: разбить последовательность чисел от 1 до n * n на n подмножеств так, чтобы все они состояли из n чисел и...

Вывести массив с одинаковыми суммами столбцов
программа вычисляет сумму столбцов массива. Пытаюсь вывести дополнительно одинаковые суммы столбцов отдельно если случайно выпадают, если...

26
Модератор
 Аватар для Curry
5173 / 3545 / 536
Регистрация: 01.06.2013
Сообщений: 7,710
Записей в блоге: 9
01.06.2015, 09:17
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Shamil1 Посмотреть сообщение
Есть готовый аналог для моей map1?
Кстати, интересный вопрос. Именно для строк (String) есть функции добавляющие после своего результата строку (функции с ShowS в сигнатуре). Есть, так называемые, Builder-ы для других типов строк и контейнеров. А для просто списков что то не припомню. Видимо, потому, что для эффективных решений их не используют.
Среди http://hackage.haskell.org/packages/ неверное, что то есть.
0
Модератор
Эксперт функциональных языков программирования
3142 / 2290 / 469
Регистрация: 26.03.2015
Сообщений: 8,920
01.06.2015, 10:51  [ТС]
Цитата Сообщение от pycture Посмотреть сообщение
наверно в haskell'ом и c# варианте есть еще куда стремиться
Это да. Я же реализовал полный перебор.

Добавлено через 55 минут
Цитата Сообщение от pycture Посмотреть сообщение
оно не настолько плавает что б погрешности в секунды давать.
http://ideone.com/EdPtIT 7 [1..14] 0.46s
http://ideone.com/A3e5gi 8 [1..16] 3.01s
наверно в haskell'ом и c# варианте есть еще куда стремиться
Тут есть две тонкости.

Во-первых, groupBy в F# реализовано через hash. То есть, https://www.cyberforum.ru/cgi-bin/latex.cgi?O(N) вместо https://www.cyberforum.ru/cgi-bin/latex.cgi?O(N logN).

Во-вторых, у меня есть большие подозрения, что за счёт использования last вместо reverse Вам удаётся избежать существенной части вычислений.
Если я в F# добавляю toList, заставляя считать всё, то время существенно увеличивается.
Если я в Haskell вместо reverse использую last, то время существенно сокращается.


p.s. Если у Вас в строке 5 добавить пару квадратных скобок, то в строке 14 можно будет написать просто
combinations n lst
0
1195 / 588 / 88
Регистрация: 20.09.2012
Сообщений: 1,881
01.06.2015, 11:21
Цитата Сообщение от Shamil1 Посмотреть сообщение
Во-первых, groupBy в F# реализовано через hash
выполнение groupBy на 39202 элементах занимает 0.09s из общих 3-х http://ideone.com/ffmkwg vs http://ideone.com/kyiAFE сомнительно что проблема в этом
Во-вторых, у меня есть большие подозрения, что за счёт использования last вместо reverse Вам удаётся избежать существенной части вычислений
не вычислений, а лишнего выделения памяти в список и копирования в него элементов. все вычисления остаются на месте (язык энергичный).

Добавлено через 2 минуты
Если я в F# добавляю toList, заставляя считать всё, то время существенно увеличивается
т.к. выделяется память для хранения всех 15227432 результатов.
0
Модератор
Эксперт функциональных языков программирования
3142 / 2290 / 469
Регистрация: 26.03.2015
Сообщений: 8,920
01.06.2015, 11:30  [ТС]
Цитата Сообщение от pycture Посмотреть сообщение
39202 элементах занимает 0.09s
потому что https://www.cyberforum.ru/cgi-bin/latex.cgi?O(N)
а https://www.cyberforum.ru/cgi-bin/latex.cgi?O(N log N) занимает в https://www.cyberforum.ru/cgi-bin/latex.cgi?log 39202 раз больше времени

Цитата Сообщение от pycture Посмотреть сообщение
язык энергичный
язык энергичный, а последовательности ленивые
0
1195 / 588 / 88
Регистрация: 20.09.2012
Сообщений: 1,881
01.06.2015, 12:39
Цитата Сообщение от Shamil1 Посмотреть сообщение
в log 39202 раз больше времени
т.е. ~ 0,9 s должно получиться. должно уложиться примерно в 4 сек. ну да ладно
потому что O(N)
а почему б хаскельной версии такое же не использовать?
0
Супер-модератор
Эксперт функциональных языков программированияЭксперт Python
 Аватар для Catstail
38228 / 21160 / 4314
Регистрация: 12.02.2012
Сообщений: 34,774
Записей в блоге: 14
01.06.2015, 19:15
Набросок. Как известно, каждый элемент множества всех подмножеств множества мощности N однозначно соответствует целому из диапазона [0,..2N-1]. Это позволяет использовать несколько другой подход:

Haskell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
-- Преобразовать число в битовую последовательность 
-- (знаю, можно подключить Data.Bits...)
 
int2bit :: Int -> String
int2bit n | (n <= 1) = [chr $ n+48]
          | otherwise = (chr $ 48+(n `mod` 2)) : int2bit (n `div` 2)  
 
-- Проверить что в битовом представлении числа p содержится
-- не более m единиц
 
chkN :: Int -> Int -> Bool
chkN m p = (length $ filter (/= '0') (int2bit p)) <= m
 
-- По заданному списку и числу m вычислить сумму элементов списка,
-- соответствующих битовому представлению m
 
sumB :: [Int] -> Int -> Int
sumB l m = f l (int2bit m)
         where f [] _ = 0
               f _ [] = 0
               f (x:xs) (y:ys) = (if (y=='1') then x else 0) + f xs ys
              
-- Построить базовое множество чисел (в битовом разложении которых
-- не более m единиц)
 
base :: [Int] -> Int -> [Int]
base x m = filter (chkN m) [1,2..2^n]
           where n = length x
           
-- Построить список пар (x,y) где x элемент базового множества,
-- а у - сумма соответствующих элементов списка
 
pairs :: [Int] -> Int -> [(Int,Int)]
pairs l m = map (\ x -> (x ,sumB l x)) $ base l m           
 
-- теперь достаточно найти пары, у которых совпадают вторые элементы
0
Модератор
 Аватар для Curry
5173 / 3545 / 536
Регистрация: 01.06.2013
Сообщений: 7,710
Записей в блоге: 9
01.06.2015, 20:28
Цитата Сообщение от Catstail Посмотреть сообщение
По заданному списку и числу m вычислить сумму элементов списка,
-- соответствующих битовому представлению m
Это так каждый раз по списку бегать?
Цитата Сообщение от Catstail Посмотреть сообщение
Построить список пар (x,y) где x элемент базового множества,
-- а у - сумма соответствующих элементов списка
Смысл идеи не понял.

Во первых, нужно перебрать подмножества - эту задачу недавно рассматривали. Разве что сразу ограничиваться длиной подпоследовательностей не более заданной, в процессе формирования подпоследовательностей. Это может дать выигрыш.
Потом для каждого непустого подмножества длины не более заданной вычисляется сумма. Тут, лучше всего их сразу в контейнер типа словаря класть (Data.Map) где ключ - сумма, а значение - список подмножеств с такой суммой. Формирование такого словаря происходит быстро, за счёт быстрого поиска в нём при вставке/замене.
Дальше, думаю, понятно.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
01.06.2015, 20:28

Создать и заполнить третий массив, суммами чисел с одинаковыми индексами
Даны два двумерные массивы одинакового размера, заполнение случайными числами. Создать и заполнить третий массив, суммами чисел с...

Подпоследовательности С#
Помогите решить задачу. Дан массив: {xi}, i = 1...n. Найти номера начального и конечного элементов последней подпоследовательности...

Выражение с суммами
Необходимо посчитать выражение с 2-мя суммами a+Ʃ(2*l^3+3*l^2+1) 2+Ʃ(k^2+2) для l от...

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

последовательность и ее подпоследовательности
существует например последовательность xn=\lg x * sin(\pi *x/2) предел ее подпоследовательность x2n=0 - сходящаяся а x2n+1=\propto -...


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

Или воспользуйтесь поиском по форуму:
27
Ответ Создать тему
Новые блоги и статьи
Про "Windows must die!"
kumehtar 04.11.2026
Знаете, чет накатило. . . . Когда-то это было почти боевым кличем: мол, нормальный человек сидит на DOS, OS/ 2 или Linux, а вот это вот - Must Die. А теперь человек произносит «мастдай» с усмешкой - и. . .
Красочные поля с номером страницы svg+background-image
russiannick 04.11.2026
Красочные поля с номером страницы не менее важны чем в эпоху бумажных книг. Посему спешу представить почтеннейшей публике этот важный инструмент который эти поля и формирует. В процессе разработки. . .
Вступаем в новую фазу генерации favicons, векторную.
russiannick 02.11.2026
Теперь нет нужды скрывать что используется простой svg. Исходный код изображения помещаем в поле и жмем кнопку. Исходник преобразуется в вид корректный для помещения в favicon или в url(). Нажатие. . .
Генератор паролей (вариант №4)
Maks 01.11.2026
После публикации 3-го варианта генератора паролей, разослал его своим коллегам (с целью оценки), в итоге были получены следующие рекомендации: 1. Вернуть возможность использования знаков | 1 l I;. . .
Генератор паролей (вариант №3)
Maks 30.10.2026
Финальная версия генератора паролей 1С. Доработка решения в этот раз коснулась только визуальной части, а именно, добавлен реквизит ДопПараметры (тип Булево), который скрывает/ отображает реквизиты:. . .
Магическое мышление и магия, современная наука не отличима от магии (говорит ИИ Джемени)
zorxor 30.10.2026
Джемени, расскажи, пожалуйста, что такое магическое мышление, что такое магия, почему современная наука чем-то напоминает магию? Фраза «Любая достаточно развитая технология неотличима от магии». . .
За какое время ИИ может подобрать пароль по хешу (рассказывает Джемени ИИ)
zorxor 30.10.2026
Расскажи, Джемени, если известен хэш МД5, например, за сколько ИИ сможет подобрать соответствующий пароль? Искусственный интеллект (ИИ) может подобрать простой или средний по сложности пароль по. . .
Кто убил Suno? Почему наше солнышко погасло? (диалог с ИИ Джемени)
zorxor 30.10.2026
Как убивали Suno. Хронология. «Убийство» музыкальной нейросети Suno — это затяжной процесс, в котором технологический хайп стартапа разбился о жесткую реальность судебных исков от гигантов. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru