Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Сортировка по нескольким параметрам 
V
    Опции темы
Bikutoru
Дата 3.12.2006, 16:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Увлекающийся
**


Профиль
Группа: Участник
Сообщений: 522
Регистрация: 24.5.2005
Где: Москва

Репутация: нет
Всего: 22



Добрый день!
У меня возникла задача: необходимо "вытащить" из текста список слов, и вывести их, предварительно отсортировав по частоте вхождения (если несколько слов имеют одинаковую частоту, то они должны быть отсортированы по алфавиту). Вот с последней частью у меня и возникла проблема. 
На первый взгляд, ничего сложного в этом нет, берем слова, записываем их хеш, где в качестве ключа используется слово, а в качестве значения частота его вхождения и пишем в стиле a-la PERL что-то вроде
Код

# пример входных данных
DATA = {
  'hello' => 20, 
  'foo'   =>  2,
  'world' => 10, 
  'and'   => 25, 
  'you'   =>  5,
  'or'    => 25, 
  'how'   => 10,
  'are'   =>  5,
}

DATA.sort { |a, b| 
  -(a[1] <=> b[1]) || (a[0] <=> b[0])
}.each { |pair| printf "%03d: %s\n", pair[1], pair[0] }

и получаем... правильно, не совсем то, что нужно. Выведенные данные действительно отсортированы по частоте вхождения, но вот с алфавитом имеются определённые проблемы. Сижу, разбираюсь и прихожу к выводу, что 0 есть истина (о чём, кстати, в "Programming Ruby" честно написано - "Any value that is not nil or the constant false is true")! 
Хорошо, тогда на мне  ум приходит другая "гениальная" мысль - а давайте-ка использовать побитовое ИЛИ, что гарантировано даст возможность вычисления всех "сравнений". Да, но ведь в этом случае мы можем получитьвыражение 1 | -1, которое даст совсем не тот результат, который нужен. Следовательно, этот вариант тоже не подходит. В результате я пришел в селдующему варианту:
Код

class Array
  def compare_result
    self.find { |condition| not condition.zero? } || 0
  end
end

DATA.sort { |a, b| 
  [-(a[1] <=> b[1]), a[0] <=> b[0]].compare_result 
}.each { |pair| printf "%03d: %s\n", pair[1], pair[0] }

Ну и, наконец, озвучу свой вопрос - а не дурак ли я нет ли более простого варианта для решения задачи сортировки по нескольким условиям сразу? Меня не оставляет мысль, что это должно решаться как-то проще...

Это сообщение отредактировал(а) Bikutoru - 3.12.2006, 16:16


--------------------
Человек, словно в зеркале мир — многолик, 
Он ничтожен — и он же безмерно велик!
Омар Хайям
PM   Вверх
Pete
Дата 3.12.2006, 21:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 318
Регистрация: 5.1.2006
Где: Москва

Репутация: 2
Всего: 12



Код

DATA.sort { |a, b| 
  a[1] < b[1] ? 1 : a[1] > b[1] ? -1 : a[0] <=> b[0]
}.each { |pair| printf "%03d: %s\n", pair[1], pair[0] }


Это сообщение отредактировал(а) Pete - 10.12.2006, 19:58


--------------------
Совет учиться на ошибках других бесполезен; научиться чему-либо можно только на собственных ошибках. (Бернард Шоу)
Не откладывай на завтра то, что можешь сделать сегодня. (Пословица)
А теперь выпишем точное значение числа пи... (Препод)
Жахни, Пендальф! © Гоблин
PM   Вверх
Bikutoru
Дата 4.12.2006, 12:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Увлекающийся
**


Профиль
Группа: Участник
Сообщений: 522
Регистрация: 24.5.2005
Где: Москва

Репутация: нет
Всего: 22



Pete, как увидел твое решение, сразу пришло на ум небольшое упрощение:
Код

DATA.sort { |a, b| 
  (a[1] == b[1]) ? (a[0] <=> b[0]) : -(a[1] <=> b[1]) 
}.each { |pair| printf "%03d: %s\n", pair[1], pair[0] }

Спасибо, именно такой взгляд со стороны и нужен был :-)


--------------------
Человек, словно в зеркале мир — многолик, 
Он ничтожен — и он же безмерно велик!
Омар Хайям
PM   Вверх
FunnyFalcon
Дата 5.12.2006, 12:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 76
Регистрация: 27.3.2006

Репутация: 3
Всего: 7



??????????
Код

DATA.sort_by {|v| [v[1], v[0]] }.each {|pair| printf "%03d: %s\n", pair[1], pair[0] }

PM MAIL   Вверх
V.A.KeRneL
  Дата 10.12.2006, 13:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Vadim A. Kazantsev
**


Профиль
Группа: Участник
Сообщений: 291
Регистрация: 3.12.2006
Где: Moscow, Russia

Репутация: 1
Всего: 14



Цитата(FunnyFalcon @ 5.12.2006,  12:07)
??????????
Код

DATA.sort_by {|v| [v[1], v[0]] }.each {|pair| printf "%03d: %s\n", pair[1], pair[0] }

Минусик забыли! smile
Вот так будет, что надо: 
Код

DATA.sort_by {|v| [-v[1], v[0]] }.each {|pair| printf "%03d: %s\n", pair[1], pair[0] }


Моё стандартное решение с использованием метода `nonzero?': 
Код

DATA.sort { |a, b| 
    (-(a[1] <=> b[1])).nonzero? || (a[0] <=> b[0])
}.each { |pair| printf "%03d: %s\n", pair[1], pair[0] }



Это сообщение отредактировал(а) V_A_KeRneL - 11.12.2006, 02:01


--------------------
«C'est un pense-creux d'ici. C'est le meilleur et le plus irascible homme du monde...» © Ф.М. Достоевский, «Бесы»
---/)/)---(\.../)---(\(\
--(':'=)---(=';'=)---(=':')
(")(")..)-(").--.(")-(..(")(")

PM MAIL IM ICQ AOL YIM MSN   Вверх
Bikutoru
Дата 12.12.2006, 12:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Увлекающийся
**


Профиль
Группа: Участник
Сообщений: 522
Регистрация: 24.5.2005
Где: Москва

Репутация: нет
Всего: 22



FunnyFalconV_A_KeRneL, спасибо за предложенные решения. Мне они понравились гораздо больше...

Добавлено @ 12:32 
Правда проверить раньше выходных на реальных данных не получится...


--------------------
Человек, словно в зеркале мир — многолик, 
Он ничтожен — и он же безмерно велик!
Омар Хайям
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Ruby: Общие вопросы"
source777
  • С чего начать? начинаем
  • Ссылки на полезные ресурсы смотрим тут
  • Обязательно следуйте правилам Vingrad.
  • Пожалуйста, прочитайте рекомендации по работе в форуме и навигации по Vingrad.
  • Для вставки кодов Ruby используйте тег: [code=ruby]код[/code]. Когда в будущем подсветка синтаксиса для Ruby будет реализована, весь исходных код преобразится.
  • Используйтe чекбокс "Транслит" (возле кнопок кодов), если у Вас нет русских шрифтов.
  • Помните, для каждого вопроса должна быть своя тема.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, source777.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Ruby: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0881 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.