Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: недецкая задача  (Прочитано 12489 раз)
0 Пользователей и 1 Гость смотрят эту тему.
jufj
Гость
« : 09-11-2009 12:51 » 

вот задача:

не перемещая значений компонентов массива Х (varX: aaray [1..n] of integer; 1<=X[i] <=m, m <<n), найти все числа, которые встречаются в нём ровно три раза
« Последнее редактирование: 02-04-2010 08:37 от Алексей1153++ » Записан
x77
Команда клуба

ro
Offline Offline
Пол: Мужской
меняю стакан шмали на обратный билет с Марса.


« Ответ #1 : 09-11-2009 12:54 » 

для всех x (i) надо посчитать кол-во вхождений x (i) в x. задача децкая.
Записан

Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #2 : 09-11-2009 13:35 » 

x77, в общем случае - не очень детская Улыбаюсь Вариация этой задачи в SICP в 3й части есть. Правда, в контексте языка Scheme и потоков (streams) с отложенными вычислениями. Но всё равно, реализация общего алгоритма не так проста для больших n.

jufj, что именно не получается сделать?
Записан
x77
Команда клуба

ro
Offline Offline
Пол: Мужской
меняю стакан шмали на обратный билет с Марса.


« Ответ #3 : 09-11-2009 13:42 » 

Вад, не догоняю, в чём там трудность. послушаю пока остальных Улыбаюсь
Записан

Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #4 : 09-11-2009 13:47 » 

Завести map (например, hash), где ключ - число, значение - количество. 1 раз пройти массив, заполняя map, 1 раз пройти map, отбирая те пары, в которых значение = 3, и выводя ключ этой пары.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
x77
Команда клуба

ro
Offline Offline
Пол: Мужской
меняю стакан шмали на обратный билет с Марса.


« Ответ #5 : 09-11-2009 13:54 » 

обычным сетом можно обойтись. далее в цикле считать кол-во вхождений каждого числа. если кол-во = 3 - удалить все вхождения из массива, а число добавить в результирующий сет.

может я не выспался просто, и после суток за компом туплю?
Записан

Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #6 : 10-11-2009 07:23 » 

Вад, не догоняю, в чём там трудность. послушаю пока остальных Улыбаюсь

Ок. Надеюсь, Димка не обидится, что я ем его хлеб и, возможно, плохо пережёвываю Улыбаюсь

В самой задаче нет почти ничего сложного. Но я придерживаюсь взгляда, что каждое учебное задание должно лишь отчасти подразумевать решение конкретной задачи. И, в большей мере, обучать умению решать класс родственных задач.


Но что такое класс родственных задач? Скажем, данную задачу можно расширить как "найти все числа, которые встречаются ровно k раз". Но это узко: оно фактически даже не меняет алгоритм решения, просто вводит переменную вместо "избыточной" константы. Это тоже хорошо, но на этом останавливаться рано.

Далее, можно рассмотреть два подхода: первый - уже известный - упорядочение результата (аккумулирование его в map или multiset, в терминах STL; да хоть просто в массив). Второй - упорядочение входных данных (сортировка). Очевидно, что первый вариант применительно к данной задаче выглядит в целом лучше второго: сложность первого, с учётом вставки в ассоциативный контейнер, n*log(dim(mx)) (где dim(mx) - количество различных числел, встречающихся в x); сложность второго - n*log(n), и ясно, что dim(mx) <= n всегда.

Пока получается, что наш подход достаточно универсальный. Но что, если m (точнее, dim(mx)) и n - очень велики? Настолько, что у нас будут проблемы с ассоциативным массивом? Если они бесконечны?
Такая задача тоже имеет смысл, но в иной постановке: допустим, нам не нужно находить все числа "встречающиеся k раз". Достаточно первых r штук. Тогда мы можем решать задачу на бесконечных входных данных, при одном вспомогательном условии: данные должны быть упорядочены. Иначе мы не можем ничего.

Конечно, я сейчас привожу несколько искусственный пример. Это только для того, чтобы связать данную задачу с её разновидностью в SICP и проиллюстрировать, что в учебных целях лучше решать всё более и более общие задачи, не ограничиваясь "разумным пределом обобщения". Мера обобщения потом приходит с практикой, а вот широту мышления потом, уже закостенев в решении частных задач, развивать сложновато.
« Последнее редактирование: 10-11-2009 07:27 от Вад » Записан
Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #7 : 10-11-2009 07:50 » 

Теперь про то, как ставятся задачи в упомянутом SICP. Там потребность в обобщении актуализируется с самого начала. То есть, сначала обучаемому показывают механизмы абстракции, а потом неявно подталкивают к обобщениям, заставляя решать родственные задачи. Причём делают это мягко и намёками, так, чтобы внимательный ученик сам почувствовал подвох и задумался над более общим решением.

Возвращаясь к примеру. В SICP похожая задача задаётся в следующем контексте: есть потоки (streams), которые суть отложенные вычисления с мемоизацией. То есть, это как бы обычные списки, но хвост списка вычисляется только по необходимости (и результат запоминается). Таким образом, если мы хотим получить только первых 10 элементов списка, то и вычислим только 10. Ленивые вычисления позволяют задавать бесконечные структуры, которые незамедлительно используются в "математических" целях: скажем, задаётся список integers, потенциально содержащий "все целые числа" (на самом же деле - содержит лишь обещание предоставить каждое следующее число по требованию).

Далее, над потоками вводится ряд операций, позволяющих довольно широкий спектр манипуляций. Чтобы не вдаваться в подробности, просто приведу текст двух заданий, поскольку речь ведь о постановке задач, а не о частных абстракциях:
Цитата
Упражнение 3.71.
Числа, которые можно выразить в виде суммы двух кубов более, чем одним способом, иногда называют числами Рамануджана (Ramanujan numbers), в честь математика Шринивасы Рамануджана. Упорядоченные потоки пар предлагают изящное решение для задачи порождения таких чисел. Чтобы найти число, которое можно двумя разными способами записать в виде суммы двух кубов, требуется только породить поток пар натуральных чисел (i, j), взвешенных согласно сумме i^3 + j^3, и искать в этом потоке две пары подряд с одинаковым весом.
Напишите процедуру для порождения чисел Рамануджана. Первое такое число 1729. Каковы следующие пять?

Упражнение 3.72.
Используя метод, подобный описанному в упражнении 3.71, породите поток всех чисел, которые можно записать как сумму двух квадратов тремя различными способами (и покажите, каковы эти способы).

Как я говорил раньше, упражнение 3.72 является вариацией на тему задания топикстартера. Только тут всё повёрнуто другой стороной: требуется породить упорядоченный по весу поток пар и отфильтровать его таким образом, чтобы остались только те пары, значение суммы квадратов которых встречается трижды во всём (бесконечном) потоке.

В общем, легко заметить, что задача 72 аналогична задаче 71 за исключением того, что требуется найти не "двухкратное и более" вхождение пар с одним весом, а строго трёхкратное; а также, в качестве функции веса (то есть, упорядочивающей функции) используется не сумма кубов, а сумма квадратов. По-моему, намёк на то, "а нельзя ли это как-нибудь обобщить?" - весьма явный. Речь, разумеется, не об обобщении, связанном с весами, - оно к этому моменту уже существует. А о том, чтобы находить числа, представляемые k способами или k+ способами.

Намёк становится ещё более явным именно от такой постановки задачи - обработка списков-потоков. Ведь вытащить два элемента из головы и сравнить - это ещё куда ни шло (кстати, решение отчасти ошибочно, поскольку потенциально может приводить к дублированию результата).
Но решать задачу "найти ровно три вхождения" - означает, вытаскивать до 4х элементов из потока. Выглядит уж очень ненатурально и "дубово".
« Последнее редактирование: 10-11-2009 07:58 от Вад » Записан
x77
Команда клуба

ro
Offline Offline
Пол: Мужской
меняю стакан шмали на обратный билет с Марса.


« Ответ #8 : 10-11-2009 08:28 » 

Вад, идея понятна, спасибо, было интересно Улыбаюсь но боюсь, что я уже давно "закостенел в решении частных задач".

даже если воспринимать массив элементов с запретом на перемещение оных как поток, я бы просто завёл второй поток (массив), в который складывал цифры по мере поступления в уже отсортированном виде (условием это не запрещено). если поток потенциально бесконечен (что реализуемо на динамических структурах) - задача не решаема. если конечен, то после останова задача сведётся к поиску в потоке последовательностей из трёх чисел.

такое решение менее дубово (надеюсь), но приемлемо исключительно для эстетствующих преподов на экзамене, на практике за это надо рвать руки.

видимо, в этом и заключается моя закостенелость - любое решение я оцениваю с точки зрения безопасности его практического использования, надёжности и простоты используемых алгоритмов, и "кондовости" (в хорошем смысле) результирующего исходного кода.
Записан

Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #9 : 10-11-2009 08:37 » 

x77, думаю, надёжность и простота хороши там, где они хороши - в реальной работе Ага И на практике, действительно, надо рвать руки за чрезмерные навороты и абстракции.

Поэтому я и говорю, что эта задача может быть не так проста с чисто "воспитательной" точки зрения. Это ведь учебная задача, и тут эстетство как раз уместно - ведь это не конкретный продукт, и кроме самого условия задачи, других условий и требований здесь нет. Составление ТЗ и работа в рамках - это уже потом Улыбаюсь
Записан
x77
Команда клуба

ro
Offline Offline
Пол: Мужской
меняю стакан шмали на обратный билет с Марса.


« Ответ #10 : 10-11-2009 08:43 » 

Вад, а ты уверен, что преподаватель топикстартера знает о Шринивасе Рамануджане? по тому, как поставлена задача - я в этом сомневаюсь.
Записан

Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #11 : 10-11-2009 08:45 » new

В этом-то и проблема Жаль Традиция задавать задачи осталась, а обычай задумываться над однотипными задачами слегка затёрли. А потом сиди разгребай чужую кучу Java-кода, дублирующего одну функциональность. С другой стороны, попытки абстракции в таком коде смотрятся ещё чудовищнее. Там сам чёрт ногу сломит, что и зачем обобщено.
Хотя задача поставлена с намёком на определённый тип решения (сразу отсекает сортировку), поэтому есть надежда.
« Последнее редактирование: 10-11-2009 08:47 от Вад » Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines