С Новым годом! Форум программистов, компьютерный форум, киберфорум
Lisp
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.62/13: Рейтинг темы: голосов - 13, средняя оценка - 4.62
Модератор
Эксперт функциональных языков программированияЭксперт Python
37432 / 20804 / 4280
Регистрация: 12.02.2012
Сообщений: 34,219
Записей в блоге: 14
1

Найти три максимальных элемента числового списка за время O(n), где n-длина списка

07.02.2014, 10:43. Показов 2341. Ответов 20
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Мое решение:

Lisp
1
2
3
4
5
6
7
8
9
10
11
12
(defun 3max (lst &optional (m1 (car lst)) (m2 (car lst)) (m3 (car lst)))
  (cond ((null lst) (list m1 m2 m3))
        ((> (car lst) m1) (3max (cdr lst) (car lst) m1 m2))
        ((> (car lst) m2) (3max (cdr lst) m1 (car lst) m2))
        ((> (car lst) m3) (3max (cdr lst) m1 m2 (car lst)))
        (t (3max (cdr lst) m1 m2 m3))))
 
==> 3max
 
(3max '(1 2 3 4 1 2 6 3))
 
==> (6 4 3)
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
07.02.2014, 10:43
Ответы с готовыми решениями:

Из произвольного списка и числового списка построить новый список
Доброго времени суток, прощу помощи с одной задачкой. Желательно объяснение, а не решение, хотелось...

Для исходного сложного числового списка, построить список, состоящий из элементов исходного списка, отрицательные числа в котором заменены 0
Для исходного сложного числового списка, построить список, состоящий из элементов исходного списка,...

Удаление элемента, стоящего посередине списка (если длина списка нечетна)
Написать функцию, которая удаляет из списка элемент, стоящий в середине (удалённый от начала и...

Предикат, который формирует список из номеров максимальных элементов числового списка
помогите пжлст. знаю только что в теории мы будет проходит сначала по списку и находит самый...

20
Эксперт функциональных языков программированияЭксперт Java
4544 / 2738 / 486
Регистрация: 28.04.2012
Сообщений: 8,648
07.02.2014, 15:11 2
Lisp
1
2
3
4
5
6
7
8
9
10
11
12
(defun 3max (xs &aux (x (car xs)))
  (let ((a x) (b x) (c x))
    (dolist (x (cdr xs))
      (cond ((> x a) (setf c b b a a x))
            ((> x b) (setf c b b x))
            ((> x c) (setf c x))))
    (values a b c)))
 
(3max '(1 2 3 4 1 2 6 3))
; 6
; 4
; 3
1
Модератор
Эксперт функциональных языков программированияЭксперт Python
37432 / 20804 / 4280
Регистрация: 12.02.2012
Сообщений: 34,219
Записей в блоге: 14
07.02.2014, 15:21  [ТС] 3
korvin_, да, массовый setf очень к месту!
0
Заблокирован
07.02.2014, 15:28 4
Lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
;;; лямбда-стайл
(defun 3max (lst)
  ((lambda (f-rec) (f-rec lst '()))
    (lambda (lst acc)
      (if (cddr acc)
    (reverse acc)
    ((lambda (m) (f-rec (vl-remove m lst) (cons m acc)))
      (apply 'max lst))))))
 
;;; г*вн*стайл
(defun 3max (lst)
  (setq m (apply 'max lst) acc (list m))
  (repeat 2
    (setq
      lst (vl-remove m lst)
      m   (apply 'max lst)
      acc (cons m acc)))
  (reverse acc))
1
Эксперт функциональных языков программированияЭксперт Java
4544 / 2738 / 486
Регистрация: 28.04.2012
Сообщений: 8,648
07.02.2014, 15:50 5
Цитата Сообщение от Catstail Посмотреть сообщение
korvin_, да, массовый setf очень к месту!
Да, вполне, а что? Массовые car/cdr лучше? =))
0
4527 / 3521 / 358
Регистрация: 12.03.2013
Сообщений: 6,038
07.02.2014, 16:15 6
Lisp
1
2
3
4
5
6
(use-package "TRACK-BEST")
 
(defun foo (xs &optional (keep 3))
  (with-track-best (:keep keep)
    (dolist (x xs)
      (track x x))))
2
Модератор
Эксперт функциональных языков программированияЭксперт Python
37432 / 20804 / 4280
Регистрация: 12.02.2012
Сообщений: 34,219
Записей в блоге: 14
07.02.2014, 16:26  [ТС] 7
korvin_, я не иронизировал. У Вас действительно изящный код. И мой можно было бы чуть облагородить:

Lisp
1
2
3
4
5
6
7
(defun 3max (lst &optional (m1 (car lst)) (m2 (car lst)) (m3 (car lst)))
  (let ((ca (car lst)) (cd (cdr lst))
    (cond ((null lst) (list m1 m2 m3))
             ((> ca m1) (3max cd ca m1 m2))
             ((> ca m2) (3max cd m1 ca m2))
             ((> ca m3) (3max cd m1 m2 ca))
             (t (3max cd m1 m2 m3)))))
Добавлено через 7 минут
ur_naz, строго говоря, Вы тоже правы. Трехкратное применение max с удалением результата - это сложность тоже O(n).
0
Заблокирован
07.02.2014, 17:31 8
Цитата Сообщение от Catstail Посмотреть сообщение
это сложность тоже O(n).
если честно не совсем понял смысла...
ну вот совсем простой вариант
Lisp
1
2
3
(defun 3max (lst)
  ((lambda (x) (list (car x) (cadr x) (caddr x)))
    (vl-sort lst '>)))
Скорость работы ведь зависит не только от длины списка, но и от его содержимого, так что мои варианты могут уделать ваш, а могут и слиться.
Проблема в том, что ваш код у меня споткнется где-то на 20тыс. элементов, а мой отработает нормально.
0
Модератор
Эксперт функциональных языков программированияЭксперт Python
37432 / 20804 / 4280
Регистрация: 12.02.2012
Сообщений: 34,219
Записей в блоге: 14
07.02.2014, 18:02  [ТС] 9
Цитата Сообщение от ur_naz Посмотреть сообщение
ну вот совсем простой вариант
- этот вариант делает много лишнего: он сортирует список, а это - значительно бОльшие затраты ресурсов. И у самых лучших сортировок сложность O(n*log2n).

Цитата Сообщение от ur_naz Посмотреть сообщение
Скорость работы ведь зависит не только от длины списка, но и от его содержимого,
- для числовых списков навряд ли...
1
2304 / 1063 / 77
Регистрация: 12.03.2013
Сообщений: 4,987
08.02.2014, 16:45 10
Lisp
1
2
3
4
5
6
(defun f (xs)
  (destructuring-bind (%1 %2 %3 &rest xs) xs
    (reduce #'(lambda (xs x &aux (xs (cons x xs)))
                (remove (reduce #'min xs) xs))
            xs
            :initial-value (list %1 %2 %3))))
Добавлено через 38 минут
Усложняю Количество максимальных элементов должно задаваться аргументом функции.

Добавлено через 25 минут
Lisp
1
2
3
4
5
6
7
8
(defun f (xs &optional (n 1))
  (let ((init (subseq xs 0 n))
        (rest (nthcdr n xs)))
    (reduce #'(lambda (xs x &aux (xs (cons x xs)))
                (remove (reduce #'min xs)
                        xs))
            rest
            :initial-value init)))
1
Модератор
Эксперт функциональных языков программированияЭксперт Python
37432 / 20804 / 4280
Регистрация: 12.02.2012
Сообщений: 34,219
Записей в блоге: 14
08.02.2014, 20:48  [ТС] 11
Цитата Сообщение от nullxdth Посмотреть сообщение
Усложняю
- хорошее дополнение... При количестве максимальных, близких к размеру исходного массива, задача "плавно перетекает" в задачу сортировки. И уже не решается за время O(n)
0
2304 / 1063 / 77
Регистрация: 12.03.2013
Сообщений: 4,987
08.02.2014, 22:54 12
Цитата Сообщение от Catstail Посмотреть сообщение
И уже не решается за время O(n)
Нет. Сложность всё равно будет линейной. Просто стоимость шага определяется количеством.
0
Модератор
Эксперт функциональных языков программированияЭксперт Python
37432 / 20804 / 4280
Регистрация: 12.02.2012
Сообщений: 34,219
Записей в блоге: 14
09.02.2014, 11:32  [ТС] 13
nullxdth, что-то у меня Ваш код в LispWorks возвращает nil. Вообще же, этот алгоритм эквивалентен частичной сортировке выбором. Если задавать n близким к размеру массива, затраты будут близки к O(n2)
0
4527 / 3521 / 358
Регистрация: 12.03.2013
Сообщений: 6,038
09.02.2014, 17:01 14
Цитата Сообщение от Catstail Посмотреть сообщение
nullxdth, что-то у меня Ваш код в LispWorks возвращает nil. Вообще же, этот алгоритм эквивалентен частичной сортировке выбором. Если задавать n близким к размеру массива, затраты будут близки к O(n2)
Дык два параметра, n и k, сложность - O(nk). Если k фиксировать, получается O(n).
1
Модератор
Эксперт функциональных языков программированияЭксперт Python
37432 / 20804 / 4280
Регистрация: 12.02.2012
Сообщений: 34,219
Записей в блоге: 14
09.02.2014, 18:00  [ТС] 15
Цитата Сообщение от helter Посмотреть сообщение
Если k фиксировать, получается O(n).
берем k=n и фиксируем. Получаем алгоритм сортировки сложности O(n), что есть выдающийся результат... Нет?
0
4527 / 3521 / 358
Регистрация: 12.03.2013
Сообщений: 6,038
09.02.2014, 18:09 16
Цитата Сообщение от Catstail Посмотреть сообщение
берем k=n и фиксируем. Получаем алгоритм сортировки сложности O(n), что есть выдающийся результат... Нет?
Гм. Ну как-то нет. Вы не можете зафиксировать n, поэтому не можете зафиксировать k = n. Это же фиксация относительно n - n идёт к бесконечности, k остаётся.

Когда вы пишете O(<что-нибудь>), весь смысл в том, что <что-нибудь> не фиксируется, а устремляется, например, к бесконечности. Это нотация для асимптотического поведения. Если a_n = O(n), то асимптотически a_n растёт не более чем линейно, когда n растёт.
1
2304 / 1063 / 77
Регистрация: 12.03.2013
Сообщений: 4,987
09.02.2014, 19:12 17
helter, всё верно. Я бы не смог объяснить лучше!
1
2304 / 1063 / 77
Регистрация: 12.03.2013
Сообщений: 4,987
09.02.2014, 19:19 18
Цитата Сообщение от Catstail Посмотреть сообщение
что-то у меня Ваш код в LispWorks возвращает nil.
Хм. А что на входе у вас? Я не вижу никаких проблем.
Миниатюры
Найти три максимальных элемента числового списка за время O(n), где n-длина списка  
0
Модератор
Эксперт функциональных языков программированияЭксперт Python
37432 / 20804 / 4280
Регистрация: 12.02.2012
Сообщений: 34,219
Записей в блоге: 14
09.02.2014, 19:40  [ТС] 19
nullxdth, Ваш алгоритм эквивалентен частичной сортировке выбором. Сама сортировка выбором требует:

1 проход = n просмотров;
2 проход = n-1 просмотр;
...
n проход = 1 просмотр

Итого 1+2+3+...+n=n(n+1)/2 просмотров. При стремлении n к бесконечности, эта величина растет как n2. Или я неправ? А теперь посмотрим, что меняется, если искать не "все максимальные", а n-3 или n-5. Вполне очевидно, что квадратичный характер зависимости "никуда не денется".

Мой алгоритм (будучи обобщен на случай произвольного числа максимальных) при одном просмотре исходного массива (сложность O(n)) будет требовать просмотра массива максимальных. И если количество максимальных близко к размеру исходного массива, то тоже выйдет O(n2).

Добавлено через 4 минуты
Цитата Сообщение от nullxdth Посмотреть сообщение
Хм. А что на входе у вас? Я не вижу никаких проблем.
Работает, но ищет не k, а (k-1) максимальный:

Lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
CL-USER 1 > (defun f (xs &optional (n 1))
  (let ((init (subseq xs 0 n))
        (rest (nthcdr n xs)))
    (reduce #'(lambda (xs x &aux (xs (cons x xs)))
                (remove (reduce #'min xs)
                        xs))
            rest
            :initial-value init)))
F
 
CL-USER 2 > (f '(9 4 2 1 4 2 5) 3)
 
(5 9)
Добавлено через 5 минут
Вот достаточно прозрачный код:

Lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
(defun get-n-max (lst n)
 (if (zerop n) 
     nil 
     (let ((max (apply 'max lst)))
        (cons max (get-n-max (removef max lst) (- n 1)))))) 
 
==> get-n-max
 
(get-n-max '(1 2 3 4 5 1 2 3 4 5 11 22 0 9) 4)
 
==> (22 11 9 5)
 
(get-n-max '(1 2 3 4 5 1 2 3 4 5 11 22 0 9) 5)
 
==> (22 11 9 5 5)
1
2304 / 1063 / 77
Регистрация: 12.03.2013
Сообщений: 4,987
09.02.2014, 20:11 20
Лучший ответ Сообщение было отмечено как решение

Решение

Цитата Сообщение от Catstail Посмотреть сообщение
Ваш алгоритм эквивалентен частичной сортировке выбором.
Ох. Нет, это не так. Пусть k - количество максимальных элементов которые нужно найти. Сложность будет: O(2k*n). 2 потому что ищем минимальный элемент и выбрасываем его. 2k - константа которая не зависит от n и не влияет на динамику роста сложности. Вообщем, helter, уже всё сказал как бы.

Добавлено через 6 минут
Цитата Сообщение от Catstail Посмотреть сообщение
Работает, но ищет не k, а (k-1) максимальный
Нет, это не так. Но баг действительно есть, при повторяющихся элементах!
Вот так надо переписать:
Lisp
1
2
3
4
5
6
7
8
9
(defun f (xs &optional (n 1))
  (let ((init (subseq xs 0 n))
        (rest (nthcdr n xs)))
    (reduce #'(lambda (xs x &aux (xs (cons x xs)))
                (remove (reduce #'min xs)
                        xs
                        :count 1))
            rest
            :initial-value init)))
Спасибо.

Добавлено через 10 минут
Цитата Сообщение от Catstail Посмотреть сообщение
Вот достаточно прозрачный код
Ну так это не эквивалентный алгоритм-то. В моей реализации стоимость каждого шага фиксирована (2k).
А у вас, конечно, квадратичная сложность.
3
09.02.2014, 20:11
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
09.02.2014, 20:11
Помогаю со студенческими работами здесь

Создание списка, печать списка на экран, добавления элемента в начало списка, конец списка
Построить динамическую структуру типа список . Необходимо реализовать следующие процедуры: 1....

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

Определить два максимальных элемента некоторого списка
Определить два максимальных элемента некоторого списка.

Работа с деками. Найти среднее арифметическое списка, добавить его в качестве нового элемента в начало и конец списка
D - список действительных чисел. Найти среднее арифметическое списка, добавить его в качестве...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Что такое CQRS и как это реализовать на C# с MediatR
InfoMaster 15.01.2025
Концепция CQRS и её роль в современной разработке В современном мире разработки программного обеспечения архитектурные паттерны играют ключевую роль в создании масштабируемых и поддерживаемых. . .
Как настроить CI/CD с Azure DevOps
InfoMaster 15.01.2025
CI/ CD, или непрерывная интеграция и непрерывное развертывание, представляет собой современный подход к разработке программного обеспечения, который позволяет автоматизировать и оптимизировать процесс. . .
Как настроить CI/CD с помощью Jenkins
InfoMaster 15.01.2025
Введение в CI/ CD и Jenkins В современной разработке программного обеспечения непрерывная интеграция (CI) и непрерывная доставка (CD) стали неотъемлемыми элементами процесса создания качественных. . .
Как написать микросервис на Go/Golang с Kafka и GitHub CI/CD
InfoMaster 14.01.2025
Определение микросервиса, преимущества использования Go/ Golang Микросервис – это архитектурный подход к разработке программного обеспечения, при котором приложение состоит из небольших, независимо. . .
Как написать микросервис с нуля на C# с RabbitMQ, CQRS и CI/CD
InfoMaster 14.01.2025
В современном мире разработки программного обеспечения микросервисная архитектура стала стандартом де-факто для создания масштабируемых и гибких приложений. Этот архитектурный подход предполагает. . .
Как создать интернет-магазин на PHP и JavaScript
InfoMaster 14.01.2025
В современном мире электронная коммерция стала неотъемлемой частью бизнеса. Создание собственного интернет-магазина открывает широкие возможности для предпринимателей, позволяя достичь большей. . .
Как написать Тетрис на Ассемблере
InfoMaster 14.01.2025
Тетрис – одна из самых узнаваемых и популярных компьютерных игр, созданная в 1984 году советским программистом Алексеем Пажитновым. За прошедшие десятилетия она завоевала симпатии миллионы людей по. . .
Как создать игру "Танчики" на Unity3d и C#
InfoMaster 14.01.2025
Разработка игр – это увлекательный процесс, сочетающий в себе творчество и технические навыки. В этой статье мы рассмотрим создание классической игры "Танчики" с использованием Unity3D и языка. . .
Организую платный онлайн микро-курс по доработке Android-клиента Telegram
_Ivana 14.01.2025
Официальная версия и распространенные форки не полностью устраивают? Сделай свою кастомную версию клиента! 4 занятия по 2 часа (2 недели пн, ср 19:00-21:00 по Москве). Первое вводное занятие. . .
Как создать приложение для фитнеса для iOS/iPhone на Kotlin
InfoMaster 14.01.2025
Создание собственного фитнес-приложения — это не только захватывающий, но и полезный процесс, ведь оно может стать вашим верным помощником на пути к здоровому и активному образу жизни. В современных. . .
Как создать приложение магазина для iOS/iPhone на Swift
InfoMaster 14.01.2025
Введение в разработку iOS-приложений Разработка приложений для iPhone и других устройств на базе iOS открывает огромные возможности для создания инновационных мобильных решений. В данной статье мы. . .
Это работает. Скорость асинхронной логики велика. Вопрос видимо останется в стабильности. Плата - огонь!
Hrethgir 13.01.2025
По прошлому проекту в Logisim Evolution https:/ / www. cyberforum. ru/ blogs/ 223907/ blog8781. html прилагаю файл архива проекта в Gowin Eda. Восьмибитный счётчик из сумматора+ генератор сигнала. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru