Количество повторяющихся чисел в списке

Форум пользователей пакета Maple

Модератор: Admin

berg
Сообщения: 37
Зарегистрирован: Чт янв 19, 2012 8:33 pm

Количество повторяющихся чисел в списке

Сообщение berg » Сб окт 13, 2012 9:37 am

Массив случайных чисел от 1 до 1000 представлен в виде списка.
Как составить программу, чтобы на экран выводились числа в порядке их возрастания и одновременно указывалось количество повторяющихся чисел?
Заранее благодарен.

Selin
Сообщения: 43
Зарегистрирован: Чт апр 14, 2011 11:14 am

Сообщение Selin » Сб окт 13, 2012 10:44 am

> p:=rand(1..200): k:=1000: L:=sort([seq(p(),k=1..k)]): L;

> H:=[op({op(ListTools[FindRepetitions](L))})]: seq([H[t],ListTools[Occurrences](H[t],L)],t=1..nops(H));

Далее уж сами легко домислите, получая все, что нужно и даже более.

berg
Сообщения: 37
Зарегистрирован: Чт янв 19, 2012 8:33 pm

Сообщение berg » Сб окт 13, 2012 1:44 pm

Спасибо, Selin. Интересная процедура, но я не могу домыслить, как ее применить к какому-то конкретному списку, например:
(67,19,4,90,1,5, 32,90,5,5,321).

Selin
Сообщения: 43
Зарегистрирован: Чт апр 14, 2011 11:14 am

Сообщение Selin » Сб окт 13, 2012 2:54 pm

> L:=[67, 19, 4, 90, 1, 5, 32, 90, 5, 5, 321];
L := [67, 19, 4, 90, 1, 5, 32, 90, 5, 5, 321]
> H:=[op({op(ListTools[FindRepetitions](L))})]: seq([H[t],ListTools[Occurrences](H[t],L)],t=1..nops(H));
[5, 3], [90, 2]

berg
Сообщения: 37
Зарегистрирован: Чт янв 19, 2012 8:33 pm

Сообщение berg » Сб окт 13, 2012 7:27 pm

Процедура работает, но есть один недостаток: не указываются числа, которые повторяются один раз или которых нет совсем. Это искажает общий результат. Числа, повторяющиеся один раз, необходимо указывать.
Можно ли исправить этот недостаток?

Markiyan Hirnyk
Сообщения: 1340
Зарегистрирован: Вс дек 04, 2011 11:07 pm

Модификация

Сообщение Markiyan Hirnyk » Сб окт 13, 2012 8:53 pm

berg писал(а):Процедура работает, но есть один недостаток: не указываются числа, которые повторяются один раз или которых нет совсем. Это искажает общий результат. Числа, повторяющиеся один раз, необходимо указывать.
Можно ли исправить этот недостаток?

with(ListTools):
L := [67, 19, 4, 90, 1, 5, 32, 90, 5, 5, 321];

[67, 19, 4, 90, 1, 5, 32, 90, 5, 5, 321]
{seq([x, Occurrences(x, L)], x = L)};
{[1, 1], [4, 1], [5, 3], [19, 1], [32, 1], [67, 1], [90, 2],[321, 1]}
convert(%, list);
[[1, 1], [4, 1], [5, 3], [19, 1], [32, 1], [67, 1], [90, 2],[321, 1]]

berg
Сообщения: 37
Зарегистрирован: Чт янв 19, 2012 8:33 pm

Сообщение berg » Сб окт 13, 2012 9:20 pm

Благодарю, Markiyan Hirnyk!
Просто и красиво.

Сергей46
Сообщения: 9
Зарегистрирован: Пт июл 13, 2012 7:49 pm

Сообщение Сергей46 » Пн окт 15, 2012 10:46 am

Уважаемый berg, обычно я не помогаю студентам с решением примитивных примеров. Но тут вопрос несколько сложнее и поучительнее. Г-н Selin привел довольно эффективное решение для вашего примера при условии получения лишь кратных значений списка (его совет домыслить результата не возымел); именно это яаляется более естественной постановкой, чтобы не выводить кратные пары. Г-н Markiyan Hirnyk привел решение для более простого случая (не требовалось отделять “мух от котлет”). Однако, если в первом случае использовались разовые вызовы функций (по терминологии одного автора, правда, очень точно отражающей суть), то во втором использовалась загрузка всего пакета ListTools, что неэффективно, ибо Maple очень неэффективно (в отличие от Mathematica) оптимизирует память. Наконец, более эффективно использовать встроенные, а значит и более быстрые, и имеющиеся во всех версиях средства, в частности, функцию numboccur. Вот решение вашего примера в ее терминах:

> LS := (x::list) -> [op({seq([k, numboccur(x, k)], k=x)})]:
> L := [67, 19, 4, 90, 1, 5, 32, 90, 5, 5, 321]: LS(L);
[[321, 1], [32, 1], [5, 3], [1, 1], [90, 2], [4, 1], [19, 1],[67, 1]]
> L := [a, a+b, c, c, c, c, a+b0, d, d, a+b]: LS(L);
[[d, 2], [a + b0, 1], [c, 4], [a + b, 2], [a, 4]]

Дополнительно напомню, что индекстная перемення к в функциях типа seq носит локальный характер. Остальное “домыслите”. Предложенный прием имеет массу продолжений. Надеюсь, это сподвигнет вас на более глубокое освоение Maple. К сожалению, на большую детализацию времени нет, ждут подобные студенты.

Markiyan Hirnyk
Сообщения: 1340
Зарегистрирован: Вс дек 04, 2011 11:07 pm

Сообщение Markiyan Hirnyk » Пн окт 15, 2012 2:57 pm

Сергей46 писал(а):Уважаемый berg, обычно я не помогаю студентам с решением примитивных примеров. Но тут вопрос несколько сложнее и поучительнее. Г-н Selin привел довольно эффективное решение для вашего примера при условии получения лишь кратных значений списка (его совет домыслить результата не возымел); именно это яаляется более естественной постановкой, чтобы не выводить кратные пары. Г-н Markiyan Hirnyk привел решение для более простого случая (не требовалось отделять “мух от котлет”). Однако, если в первом случае использовались разовые вызовы функций (по терминологии одного автора, правда, очень точно отражающей суть), то во втором использовалась загрузка всего пакета ListTools, что неэффективно, ибо Maple очень неэффективно (в отличие от Mathematica) оптимизирует память. Наконец, более эффективно использовать встроенные, а значит и более быстрые, и имеющиеся во всех версиях средства, в частности, функцию numboccur. Вот решение вашего примера в ее терминах:

> LS := (x::list) -> [op({seq([k, numboccur(x, k)], k=x)})]:
> L := [67, 19, 4, 90, 1, 5, 32, 90, 5, 5, 321]: LS(L);
[[321, 1], [32, 1], [5, 3], [1, 1], [90, 2], [4, 1], [19, 1],[67, 1]]
> L := [a, a+b, c, c, c, c, a+b0, d, d, a+b]: LS(L);
[[d, 2], [a + b0, 1], [c, 4], [a + b, 2], [a, 4]]

Дополнительно напомню, что индекстная перемення к в функциях типа seq носит локальный характер. Остальное “домыслите”. Предложенный прием имеет массу продолжений. Надеюсь, это сподвигнет вас на более глубокое освоение Maple. К сожалению, на большую детализацию времени нет, ждут подобные студенты.
Хорошая мысль, Ваш код примерно в 6 раз быстрее. Однако требованиям заказчика лучше соответствует sort(LS(L)) .

berg
Сообщения: 37
Зарегистрирован: Чт янв 19, 2012 8:33 pm

Сообщение berg » Пн окт 15, 2012 5:58 pm

Уважаемый Сергей46!
Вы ошибочно отнесли меня к студентам. Мне уже за 70, и я слабо владею Мэплом. Поэтому "домысливать" у меня не получается. Но я благодарен Вам за предложенную процедуру и за то, что любезно откликнулись на мой вопрос.

Сергей46
Сообщения: 9
Зарегистрирован: Пт июл 13, 2012 7:49 pm

Сообщение Сергей46 » Пн окт 15, 2012 7:54 pm

Уважаемый Berg, за “студента” не извиняюсь, ибо вы сами себя так обозвали. С остальным понятно. Рад, что в таком возрасте у вас такие серьезные интересы. Именно из уважения к вашкму возрасту решил еще раз ответить.

Уважаемый Markiyan Hirnyk! Я привел лишь основу, на базе которой можно получать решение целого ряда подобных задач (группировка элементов с одинаковыми кратностями и пр.). Это по той причине, что работая в области криптографии, я параллельно читаю курсы по алгебре и анализу для студентов. Матпакеты и программирование использую лишь как вспомогательные средства. Но мое кредо – не оказывать медвежью услугу студентам, которые в массе своей живут по принципу “сдал и забыл”. Поэтому и пытаюсь стимулировать их мысли не прямыми подсказками, а наводками. Что же до сортировки, то можно использовать нечто подобное (на примере имеющегося списка, можно привести и другие интересные варианты)

> L := [[321, 1], [32, 1], [5, 3], [1, 1], [90, 2], [4, 1], [19, 1], [67, 1]]:
> F := (x, y) -> evalb(z(x[1], y[1])): z := `<`: sort(L, F);
[[1, 1], [4, 1], [5, 3], [19, 1], [32, 1], [67, 1], [90, 2], [321, 1]]
> z := `>`: sort(L, F);
[[321, 1], [90, 2], [67, 1], [32, 1], [19, 1], [5, 3], [4, 1], [1, 1]]

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

Markiyan Hirnyk
Сообщения: 1340
Зарегистрирован: Вс дек 04, 2011 11:07 pm

Играйте простую мелодию

Сообщение Markiyan Hirnyk » Пн окт 15, 2012 8:10 pm

Сергей46 писал(а):Уважаемый Markiyan Hirnyk! Я привел лишь основу, на базе которой можно получать решение целого ряда подобных задач (группировка элементов с одинаковыми кратностями и пр.). Что же до сортировки, то можно использовать нечто подобное (на примере имеющегося списка, можно привести и другие интересные варианты)

> L := [[321, 1], [32, 1], [5, 3], [1, 1], [90, 2], [4, 1], [19, 1], [67, 1]]:
> F := (x, y) -> evalb(z(x[1], y[1])): z := `<`: sort(L, F);
[[1, 1], [4, 1], [5, 3], [19, 1], [32, 1], [67, 1], [90, 2], [321, 1]]
> z := `>`: sort(L, F);
[[321, 1], [90, 2], [67, 1], [32, 1], [19, 1], [5, 3], [4, 1], [1, 1]]

Пожалуйста, объясните, с какой целью Вы приводите "более интересные варианты"?

berg
Сообщения: 37
Зарегистрирован: Чт янв 19, 2012 8:33 pm

Сообщение berg » Пн окт 15, 2012 8:11 pm

Можно ли произвести сортировку по второму элементу?
То есть получить следующий список:
[5,3],[90,2],[1,1],[4,1],[19,1],... и т.д.

Сергей46
Сообщения: 9
Зарегистрирован: Пт июл 13, 2012 7:49 pm

Сообщение Сергей46 » Пн окт 15, 2012 8:42 pm

То Markiyan Hirnyk: А привел я лишь в порядке общей информированности. Если не интересно (будем надеяться), пропустите.

То Berg: Можно и по второму элементу (несложно усмотреть принцип)

> F := (x, y) -> evalb(z(x[2], y[2])): z:=`<`: sort(L, F);
[[67, 1], [19, 1], [4, 1], [1, 1], [32, 1], [321, 1], [90, 2], [5, 3]]