Сортировать отдельные элементы списка в порядке убывания по частоте


12

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

Пример:

Данный:

["John","Doe","Dick","Harry","Harry","Doe","Doe","Harry","Doe","John"]

Ожидаемое возвращаемое значение:

["Doe","Harry","John","Dick"]

Код-гольф или код-вызов?
Маринус

Код-гольф. Это была ошибка. Просто исправьте это
belvi

Ответы:


13

APL (14)

{∪⍵[⍒+⌿∘.≡⍨⍵]}

Это функция, которая принимает список, например:

      names
 John  Doe  Dick  Harry  Harry  Doe  Doe  Harry  Doe  John 
      {∪⍵[⍒+⌿∘.≡⍨⍵]} names
 Doe  Harry  John  Dick

Объяснение:

  • ∘.≡⍨⍵: сравнить каждый элемент в массиве с каждым другим элементом в массиве, давая матрицу
  • +⌿: сумма столбцов матрицы, показывающая, сколько раз встречается каждый элемент
  • : дать индексы нисходящего вида
  • ⍵[... ]: упорядочить по заданным показателям
  • : получить уникальные элементы

3
И все же как-то они называют переход от этого лаконичного остроумного языка к Java «прогрессом»? (-:
hippietrail

8

Питон 3 - 47 43; Python 2 - 40 39

Для Python 3:

f=lambda n:sorted(set(n),key=n.count)[::-1]

Для Python 2:

f=lambda n:sorted(set(n),cmp,n.count,1)

Демо-версия:

>>> names = ["John","Doe","Dick","Harry","Harry","Doe","Doe","Harry","Doe","John"]
>>> f(names)
['Doe', 'Harry', 'John', 'Dick']

1
Я пытался опубликовать то же самое, но вот модификация. f=lambda n:sorted(set(n),cmp,n.count,1)39 персонажей
ВЫ

1
Хм, я не понимал, что вы могли бы передать и не-None cmpфункцию, и keyфункцию. Здорово.
Blckknght

1
Немного короче:f=lambda n:sorted(set(n),key=n.count)[::-1]
grc

Благодаря @grc, инопланетный смайлик сохраняет некоторые символы в случае с Python 3.
Blckknght

5

Математика, 31

Sort[GatherBy@n][[-1;;1;;-1,1]]

{"Doe", "Harry", "John", "Dick"}

n = {"John", "Doe", "Dick", "Harry", "Harry", "Doe", "Doe", "Harry", "Doe", "John"})


Черт, ты меня там: D
Ив Клетт

@YvesKlett Спасибо. Я думаю о том, чтобы избавиться Reverse, но Sort[GatherBy@n][[-1;;1, 1]]не работает :). Есть идеи?
Аяся

Ааа, получил это mathematica.stackexchange.com/a/22320/745
Аяся

4

Математика (26 37)

С n = {"John", "Doe", "Dick", "Harry", "Harry", "Doe", "Doe", "Harry", "Doe", "John"}:

Last/@Gather@n~SortBy~Length//Reverse

{"Доу", "Гарри", "Джон", "Дик"}


Mathematica V10 + (26) :

Keys@Sort[Counts[n],#>#2&]

@garej старая версия в использовании. Опубликовать как другой ответ?
Ив Клетт

Я добавил к вашему, если вы не возражаете ...
Гарей

@garej. Спасибо, отличное решение!
Ив Клетт

3

Perl 6 (36 байт, 35 символов)

»может быть заменен на >>, если вы не можете обрабатывать UTF-8. Я почти уверен, что это может быть короче, но Bagкласс относительно странен в своем поведении (к сожалению) и не совсем завершен, так как он относительно новый (но он может считать аргументы). {}объявляет анонимную функцию.

{(sort -*.value,pairs bag @_)».key}

Пример вывода (из Perl 6 REPL):

> my @names = ("John","Doe","Dick","Harry","Harry","Doe","Doe","Harry","Doe","John")
John Doe Dick Harry Harry Doe Doe Harry Doe John
> {(sort -*.value,pairs bag @_)».key}(@names)
Doe Harry John Dick

3

Рубин: 34 37 персонажи

f=->a{a.sort_by{|z|-a.count(z)}&a}

(отредактировано: предыдущее решение с 30 символами было телом функции)


Вы можете обрезать несколько символов с помощью f=->a{a.sort_by{|z|-a.count(z)}&a}. Это &делает уникальный.
гистократ

3

GolfScript, 14 символов (19 как именованная функция, также 14 как полная программа)

:a.|{[.]a\-,}$

Этот код принимает массив в стеке и сортирует его уникальные элементы в порядке убывания по количеству вхождений. Например, если входной массив:

["John" "Doe" "Dick" "Harry" "Harry" "Doe" "Doe" "Harry" "Doe" "John"]

тогда выходной массив будет

["Doe" "Harry" "John" "Dick"]

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

{:a.|{[.]a\-,}$}:f;

Или же, чтобы превратить код в полноценную программу, которая читает список из стандартного ввода (используя приведенную выше запись списка) и печатает его в стандартный вывод, добавляя ~и добавляя `код. В [. этом случае можно опустить (так как мы знаем, что в стеке больше ничего не будет), так что получающаяся в результате 14-символьная программа будет иметь вид:

~:a.|{]a\-,}$`

Как это работает?

  • :aсохраняет копию исходного массива в переменной aдля последующего использования.

  • .| вычисляет объединение множества массива с самим собой, исключая дубликаты как побочный эффект.

  • { }$сортирует дедуплицированный массив, используя пользовательские ключи сортировки, вычисленные кодом внутри фигурных скобок. Этот код берет каждый элемент массива, использует вычитание массива, чтобы удалить его из исходного входного массива, сохраненного в a, и подсчитывает количество оставшихся элементов. Таким образом, элементы сортируются в порядке убывания частоты.

Ps. Смотрите здесь для оригинальной 30-символьной версии.


Я думаю, что это [a\])^должно быть эквивалентно [.;]a\-. Сортировка по количеству несовпадающих элементов - хорошая идея.
Питер Тейлор

Увы, нет: ^дублирует, дублирует, -нет. (И ITYM (, не ).) [a\](\-Будет работать, но не спасет никаких персонажей.
Ильмари Каронен

2

R: 23 символа

n <- c("John","Doe","Dick","Harry","Harry","Doe","Doe","Harry","Doe","John")

names(sort(table(n),T))
## [1] "Doe"   "Harry" "John"  "Dick" 

Но он использует не очень хороший ярлык Tдля TRUE...


1

если это могло бы соответствовать здесь: In sql-server

create table #t1 (name varchar(10))
insert into #t1 values ('John'),('Doe'),('Dick'),('Harry'),('Harry'),('Doe'),('Doe'),('Harry'),('Doe'),('John')


select name from #t1 group by name order by count(*) desc

ИЛИ

with cte as
(

select name,count(name) as x from #t1 group by name
)

select name from cte order by x desc

увидеть это в действии


1
Почему CTE? select name from #t1 group by name order by count(*) desc
Манатворк

1

PHP, 63 62 61 символов

function R($a){foreach($a as$v)$b[$v]++;arsort($b);return$b;}

Демо-версия:

$c = array("John","Doe","Dick","Harry","Harry","Doe","Doe","Harry","Doe","John");
$d = print_r(R($c));

Array ( [Doe] => 4 [Harry] => 3 [John] => 2 [Dick] => 1 )

взгляните на array_count_values()... Это все, что вы должны использовать (в том числе arsort())
bwoebi

array_count_values()как я вижу, не удаляет дублированные значения и не упорядочивает их.
Vereos

Он удаляет дубликаты ... Он просто не упорядочивает их ... => arsort
bwoebi

@bwoebi Вы правы. К сожалению, написание этого текста на 1 символ длиннее, чем этот ответ.
Тим Сегин

Почему путь с array_count_valuesдольше? <?$u=array_count_values($_GET);arsort($u);print_r($u);на мой взгляд 54 байта
Йорг Хюльсерманн

1

Рубин: 59 символов

f=->n{n.group_by{|i|i}.sort_by{|i|-i[1].size}.map{|i|i[0]}}

Образец прогона:

irb(main):001:0> f=->n{n.group_by{|i|i}.sort_by{|i|-i[1].size}.map{|i|i[0]}}
=> #<Proc:0x93b2e10@(irb):2 (lambda)>

irb(main):004:0> f[["John","Doe","Dick","Harry","Harry","Doe","Doe","Harry","Doe","John"]]
=> ["Doe", "Harry", "John", "Dick"]

1

Mathematica, 39 символов

f = Reverse[First /@ SortBy[Tally@#, Last]] &

names = {"John", "Doe", "Dick", "Harry", "Harry",
         "Doe", "Doe", "Harry", "Doe", "John"};

f@names

{Доу, Гарри, Джон, Дик}


1

JavaScript (ECMAScript5): 118 113 символов

function f(n){m={}
for(i in n){m[n[i]]=m[n[i]]+1||1}
return Object.keys(m).sort(function(a,b){return m[b]-m[a]})}

http://jsfiddle.net/mblase75/crg5B/


С Гармония функций жира стрелка : f=n=>{m={};n.forEach(e=>m[e]=m[e]+1||1);return Object.keys(m).sort((a,b)=>m[b]-m[a])}. (В настоящее время только в Firefox.)
manatwork

Вы можете использовать m[n[i]]=-~m[n[i]]для приращения, и вам не нужно {} вокруг тела цикла.
Нил

1

Haskell - 53 персонажа

import Data.List
import Data.Ord

f :: (Eq a, Ord a) => [a] -> [a]
f=map head.(sortBy$flip$comparing length).group.sort

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

общая длина, включая импорт: 120

без импорта, но с подписью типа: 86

сама функция: 53


1

Clojure: 43 символа

Функция:

#(keys(sort-by(comp - val)(frequencies %)))

Демо (в репл):

user=> (def names ["John","Doe","Dick","Harry","Harry","Doe","Doe","Harry","Doe","John"])
#'user/names
user=> (#(keys(sort-by(comp - val)(frequencies %))) names)
("Doe" "Harry" "John" "Dick")

0

Perl

чтобы соответствовать данной спецификации ввода / вывода мне нужно 120 символов

s!"([^"]+)"[],]!$a{$1}++!e while(<>);print 'MostOccuring = [',join(',',map{qq("$_")}sort{$a{$a}<=>$a{$b}}keys %a),"]\n"

самый короткий код, беря один элемент в строку и печатая один элемент в строке, мне нужно всего 55 символов

$a{$_}++ while(<>);print sort{$a{$a}<=>$a{$b}}keys %a)

0

C #: 111 символов

List<string>M(List<string>l){return l.GroupBy(q=>q).OrderByDescending(g=>g.Count()).Select(g=>g.Key).ToList();}

(внутри класса)

var names = new List<string> {"John", "Doe", "Dick", "Harry", "Harry", "Doe", "Doe", "Harry", "Doe", "John"};
foreach(var s in M(names))
{
    Console.WriteLine(s);
}

лань

Гарри

Джон

Дик

Простое решение с использованием LINQ.


Вы также можете удалить .ToList () , так как последовательность перечисляется через foreach
Adam Speight

Это правда, но тогда мне придется изменить тип возвращаемого значения на IEnumerable <string> .
Paavohtl


0

Скала (71)

(x.groupBy(a=>a)map(t=>(t._1,t._2.length))toList)sortBy(-_._2)map(_._1)

Ungolfed:

def f(x:Array[String]) =
  (x.groupBy(a => a) map (t => (t._1, t._2.length)) toList) 
    sortBy(-_._2) map(_._1)

0

J, 8 байт

~.\:#/.~

использование

Имена хранятся в виде массива строк в штучной упаковке.

   'John';'Doe';'Dick';'Harry';'Harry';'Doe';'Doe';'Harry';'Doe';'John'
┌────┬───┬────┬─────┬─────┬───┬───┬─────┬───┬────┐
│John│Doe│Dick│Harry│Harry│Doe│Doe│Harry│Doe│John│
└────┴───┴────┴─────┴─────┴───┴───┴─────┴───┴────┘
   f =: ~.\:#/.~
   f 'John';'Doe';'Dick';'Harry';'Harry';'Doe';'Doe';'Harry';'Doe';'John'
┌───┬─────┬────┬────┐
│Doe│Harry│John│Dick│
└───┴─────┴────┴────┘

объяснение

~.\:#/.~   Input: A
    #/.~   Finds the size of each set of identical items (Frequencies)
~.         List the distinct values in A
           Note: the distinct values and frequencies will be in the same order
  \:       Sort the distinct values in decreasing order according to the frequencies
           Return the sorted list implicitly

0

CJam, 15 байт (возможно, не конкурирующих)

q~$e`{0=W*}$1f=

Это может использовать функции CJam после того, как этот вызов был опубликован. Мне лень проверять.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.