Подсчитайте слова в тексте и отобразите их


26

Код должен принимать ввод текста (необязательно может быть любой файл, stdin, строка для JavaScript и т. Д.):

This is a text and a number: 31.

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

a:2
and:1
is:1
number:1
This:1
text:1
31:1

Обратите внимание, что 31 - это слово, поэтому слово - это что-либо буквенно-цифровое, число не действует как разделитель, например, 0xAFквалифицируется как слово. Разделителями будут все, что не является буквенно-цифровым, включая .(точка) и -(дефис), таким образом, i.e.или pick-me-upприведет к 2 или 3 словам соответственно. Должен быть чувствителен к регистру Thisи thisбудет состоять из двух разных слов, 'также будет разделителем wouldnи tбудет состоять из двух разных слов wouldn't.

Напишите самый короткий код на выбранном вами языке.

Кратчайший правильный ответ до сих пор:


5
Имеет ли значение дело (т. Е. Совпадает Thisс thisи tHIs)?
Гарет

Если что-то не алфавитно-цифровое считается как разделитель, это wouldn't2 слова ( wouldnи t)?
Гарет

@Gareth Должен быть чувствительным к регистру, Thisи на thisсамом деле это два разных слова, то же самое wouldnи t.
Эдуард Флоринеску

Если бы не были 2 слова, не должно ли это быть "бы" и "нт", так как его сокращение для не будет, или это слишком много нацистской грамматики?
Теун Пронк

@TeunPronk Я пытаюсь сделать это простым, введение нескольких правил будет поощрять исключения в порядке с грамматикой, и существует множество исключений. В английском языке i.e.это слово, но если мы позволим поставить все точки в точках конец фразы будет взят, то же самое с кавычками или одиночными кавычками, и т. д.
Эдуард Флоринеску

Ответы:


27

grep и coreutils  44  42

grep -io '[a-z0-9]*'|sort|uniq -c|sort -nr

Тест:

printf "This is a text and a number: 31." |
grep -io '[a-z0-9]*'|sort|uniq -c|sort -nr

Результаты в:

  2 a
  1 This
  1 text
  1 number
  1 is
  1 and
  1 31

Обновить

  • Используйте параметр без учета регистра и более короткое регулярное выражение. Спасибо, Томас.

2
Это почти точно ответ Макеллроя на книгу Кнута « Грамотное программирование» . Единственная разница в том, что это не включает трубу в headконце.
AJMansfield

Это была моя первая мысль.
Роб

1
Разве '\ w +' не сработает?
Сильвестр

1
41 персонажа :grep -io \[A-Z0-9]*|sort|uniq -c|sort -nr
Томас

1
@ Томас: добавил это в ответ, спасибо. Я оставил в защите звездочку, потому что она расширяла имена файлов в некоторых оболочках.
Четверг,

18

Ява 8: 289

Что довольно хорошо, так как Java - это язык, не относящийся к гольфу.

import java.util.stream.*;class C{static void main(String[]a){Stream.of(a).flatMap(s->of(s.split("[\\W_]+"))).collect(Collectors.groupingBy(x->x,Collectors.counting())).entrySet().stream().sorted(x,y->x.getValue()-y.getValue()).forEach(e->System.out.println(e.getKey()+":"+e.getValue()));}

Ungolfed:

import java.util.stream.*;
class C {
    static void main(String [] args){
        Stream.of(args).flatMap(arg->Stream.of(arg.split("[\\W_]+")))
            .collect(Collectors.groupingBy(word->word,Collectors.counting()))
            .entrySet().stream().sorted(x,y->x.getValue()-y.getValue())
            .forEach(entry->System.out.println(entry.getKey()+":"+entry.getValue()));
    }
}

Запустите из командной строки:

java -jar wordCounter.jar This is a text and a number: 31.

Неправильное регулярное выражение для расщепления. Это должно быть"[^\\W_]"
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳, String.split(String regex)метод использует шаблон, соответствующий разделителю, на который нужно разделить. Так, например, "aababba".split("b")выдаст массив {"aa", "a", "", "a"}. Мое регулярное выражение [^\\w\\d]означает «символ ни в символах слова, ни в классах цифр». [^\\W_]вместо этого - «символ, который не является ни подчеркиванием, ни находится в классе, состоящем из других слов» и будет соответствовать любому символу слова, кроме подчеркивания.
AJMansfield

Извините, мой предыдущий комментарий был неверным. \wвключает в себя \d, так что \dявляется излишним. \wвключает в себя подчеркивание, которое следует рассматривать как разделитель в соответствии с вопросом. Таким образом, правильное регулярное выражение для расщепления должно быть "[\\W_]+".
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ хорошо, спасибо; Я исправил проблему.
AJMansfield

17

APL (57)

⎕ML←3⋄G[⍒,1↓⍉G←⊃∪↓Z,⍪+⌿∘.≡⍨Z←I⊂⍨(I←⍞)∊⎕D,⎕A,⎕UCS 96+⍳26;]

например

      ⎕ML←3⋄G[⍒,1↓⍉G←⊃∪↓Z,⍪+⌿∘.≡⍨Z←I⊂⍨(I←⍞)∊⎕D,⎕A,⎕UCS 96+⍳26;]
This is a text and a number: 31.
 a       2
 This    1
 is      1
 text    1
 and     1
 number  1
 31      1

Объяснение:

  • ⎕D,⎕A,⎕UCS 96+⍳26: цифры, заглавные буквы, строчные буквы
  • (I←⍞)∊: прочитать ввод, сохранить в I, посмотреть, какие из них являются буквенно-цифровыми
  • Z←I⊂⍨: разделить Iна группы буквенно-цифровых символов, сохранить вZ
  • +⌿∘.≡⍨Z: для каждого элемента в Z, посмотрите, как часто это происходит
  • Z,⍪: сопоставить каждый элемент Zпопарно с тем, сколько раз он встречается
  • G←⊃∪↓: выбрать только уникальные пары, хранить в G
  • ⍒,1↓⍉G: получить отсортированные индексы для вхождений
  • G[... ;]: изменить порядок строк Gпо заданным показателям

6
что ... the ... f .....
Ож

6
Вот почему у меня кошмары.
Thebluefish

3
@Thebluefish: APL был разработан с использованием нотации, с намерением, очень похожим на математику, а краткая нотация освобождает вас от ясного мышления. Снова как математика, когда вы впервые видите эту запись, вы склонны думать, что она вообще не ясна, но языки всегда кажутся сложными с самого начала. Было бы проще, если бы не все в одной строке, хотя ...
Фил Х

Что бы вы ни придумали в APL, я вижу только какой-то юникодный мусор, стрелки в разных направлениях и перевернутую сосну. это хуже, чем J
bebe

Может быть короче с ⎕s( help.dyalog.com/latest/Content/Language/System%20Functions/… ) и оператором нового ключа ( help.dyalog.com/latest/Content/Language/Primitive%20Operators/… ):g⌷⍨⊂⍒2⌷⍉g←{⍺,≢⍵}⌸('\w+'⎕s'\0')⍞
ngn

8

C #: 153c 144C 142C 111с 115с 118с 114с 113с

(через LINQPad в режиме «C # Statements», не включая строку ввода)

Версия 1: 142с

var s = "This is a text and a number: 31."; // <- line not included in count
s.Split(s.Where(c=>!Char.IsLetterOrDigit(c)).ToArray(),(StringSplitOptions)1).GroupBy(x=>x,(k,e)=>new{s,c=e.Count()}).OrderBy(x=>-x.c).Dump();

Ungolfed:

var s = "This is a text and a number: 31.";
s.Split(                                                     // split string on multiple separators
    s.Where(c => !Char.IsLetterOrDigit(c))                   // get list of non-alphanumeric characters in string
     .ToArray(),                                             // (would love to get rid of this but needed to match the correct Split signature)
    (StringSplitOptions)1                                    // integer equivalent of StringSplitOptions.RemoveEmptyEntries
).GroupBy(x => x, (k, e) => new{ s = k, c = e.Count() })     // count by word
 .OrderBy(x => -x.c)                                         // order ascending by negative count (i.e. OrderByDescending)
 .Dump();                                                    // output to LINQPad results panel

Полученные результаты:

Полученные результаты

Версия 2: 114с

( [\w]включает _, что неверно ! ; [A-z]включает [ \ ] ^ _ `; останавливается на [^_\W]+)

var s = "This is a text and a number: 31."; // <- line not included in count
Regex.Matches(s, @"[^_\W]+").Cast<Match>().GroupBy(m=>m.Value,(m,e)=>new{m,c=e.Count()}).OrderBy(g=>-g.c).Dump();

Ungolfed:

Regex.Matches(s, @"[^_\W]+")                                   // get all matches for one-or-more alphanumeric characters
     .Cast<Match>()                                            // why weren't .NET 1 collections retrofitted with IEnumerable<T>??
     .GroupBy(m => m.Value, (m,e) => new{ m, c = e.Count() })  // count by word
     .OrderBy(g => -g.c)                                       // order ascending by negative count (i.e. OrderByDescending)
     .Dump();                                                  // output to LINQPad results panel

Результаты: (как Версия 1)


Кстати, для версии 2 ваша версия без гольфа не совпадает с вашей версией для гольфа. И так как вы используете буквальную строку, вы можете написать@"[^_\W]"
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ - исправил опечатку и убрал лишний `` для экономии в 1 символ - спасибо !!
jimbobmcgee

7

R, 58 символов

sort(table(unlist(strsplit(scan(,""),"[[:punct:]]"))),d=T)

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

sort(table(unlist(strsplit(scan(,""),"[[:punct:]]"))),d=T)
1: This is a text and a number: 31.
9: 
Read 8 items

     a     31    and     is number   text   This 
     2      1      1      1      1      1      1 

Это короче (49 символов) sort(table(gsub("[[:punct:]]","",scan(,""))),d=T). К сожалению, оба решения не работают правильно для wouldn't.
Джурио

6

perl6: 49 символов

.say for get.comb(/\w+/).Bag.pairs.sort(-*.value)

Комбинируйте ввод для поиска соответствия \w+, помещайте полученный список слов в a Bag, запрашивайте их пары и сортируйте их по отрицательному значению. (The *является Безотносительно звезда, это не умножение здесь)

выход:

"a" => 2
"This" => 1
"is" => 1
"text" => 1
"and" => 1
"number" => 1
"31" => 1

3
Perl 6 пугает меня.
Прим

1
Каждый раз, когда я думаю о классной языковой функции, я ищу ее, и она где-то в Perl6. Вот почему это занимает много времени ...
Фил Х

Вы можете обрезать 6 символов, используя .wordsвместо .comb(/\w+/):)
Mouq

@Mouq: к сожалению, .wordsне удаляет входные данные :или .данные, как требуется :(
Ayiko

-1. _не должно быть включено в слово под постановкой задачи.
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

6

Python 101 97

import re
a=re.split('[_\W]+',input())
f=a.count
for w in sorted(set(a),key=f)[::-1]:print w,f(w)

Теперь работает с новой строкой:

$ python countword.py <<< '"This is    a text and a number: 31, and a\nnewline"'
a 3
and 2
31 1
number 1
newline 1
is 1
text 1
This 1

Это не работает, если в тексте есть новые строки или несколько последовательных пробелов.
klingt.net

@ klingt.net исправлено.
daniero

6

PHP - 84 байта

<?$a=array_count_values(preg_split('/[_\W]+/',$argv[1],0,1));arsort($a);print_r($a);

Ввод принимается в качестве аргумента командной строки, например:

$ php count-words.php "This is a text and a number: 31."

Вывод для образца строки:

Array
(
    [a] => 2
    [number] => 1
    [31] => 1
    [and] => 1
    [text] => 1
    [is] => 1
    [This] => 1
)

1
он говорит, что вход - то, что вы хотите. так что вы можете получить его в качестве параметра командной строки с помощью$argv[1]
Einacio

@Einacio хороший звонок.
Прим

-1. Подчеркивание _не должно быть включено в слово.
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ исправлено.
Примо

5

PowerShell (40)

$s -split"\W+"|group -ca|sort count -des

$ s - это переменная, которая содержит входную строку.


2
[\W]недостаточно хорош - он соответствует пробелу в моем тесте. И это не упорядочено по убыванию количества ...
jimbobmcgee

$s -split"[\W]"|group -ca|where{$_.Name -ne ""}|sort{-$_.Count}приближает вас (конечно, с затратами)
jimbobmcgee

Упс я пропустил сортировку. Скоро исправлю мой ответ.
микробиан

в качестве альтернативы:$s -split"\W+"|group -ca |sort count -des
Nacimota

4
-split"\W+"соответствует пустой строке между последним .и концом строки; также \W+матчи, _которые технически запрещены
jimbobmcgee

4

Perl 69

$h{$_}++for<>=~/\w+/g;print"$_: $h{$_}
"for sort{$h{$b}-$h{$a}}keys%h

Добавлены рекомендации от @primo и @protist


1
Как насчет сортировки?
Даниеро

@daniero, отличная точка! Это сейчас сортирует!
Дом Гастингс

1
Я думаю, что это настолько кратко, насколько это возможно. Если вы не возражаете против предупреждения об устаревании, между geи for. Также <=>оператор может быть заменен на -.
Прим

2
@primo Аааа, -а <=>не гений, не уверен, что это на советы по гольфу для Perl Thread. Я обновлю это позже, спасибо!
Дом Гастингс

1
Привет @protist, \wтоже включает числа ( perl -e 'print for"a 1 2 3 4 b"=~/\w/g'печатает a1234b), но твой механизм итерации слов сохраняет другой символ, поэтому я обновлю. Спасибо!
Дом Гастингс

4

Powershell: 57 55 53 62 57

(не включая входную строку)

$s = "This is a text and a number: 31."    # <-- not counting this line...
[Regex]::Matches($s,"[^_\W]+")|group -ca|sort{-$_.Count}

возвращает:

Count Name                      Group
----- ----                      -----
    2 a                         {a, a}
    1 and                       {and}
    1 31                        {31}
    1 number                    {number}
    1 This                      {This}
    1 is                        {is}
    1 text                      {text}

(с реквизитами @microbian для группы -ca)


3

EcmaScript 6

Версия 1 (108 символов)

s.split(_=/[^a-z\d]/i).map(x=>_[x]=-~_[x]);keys(_).sort((a,b)=>_[a]<_[b]).map(x=>x&&console.log(x+':'+_[x]))

Версия 2 (102 символа)

s.split(_=/[^a-z\d]/i).map(x=>_[x]=-~_[x]);keys(_).sort((a,b)=>_[a]<_[b]).map(x=>x&&alert(x+':'+_[x]))

Версия 3 (105 символов)

s.match(_=/\w+/g).map(x=>_[x]=-~_[x]);alert(keys(_).sort((a,b)=>_[a]<_[b]).map(x=>x+':'+_[x]).join('\n'))

Версия 4 (94 символа)

s.match(_=/\w+/g).map(x=>_[x]=-~_[x]);keys(_).sort((a,b)=>_[a]<_[b]).map(x=>alert(x+':'+_[x]))

Версия 5 (без предупреждения; 87 символов)

s.match(_=/\w+/g).map(x=>_[x]=-~_[x]);keys(_).sort((a,b)=>_[a]<_[b]).map(x=>x+':'+_[x])

Версия 6 (100 знаков)

keys(_,s.match(_=/\w+/g).map(x=>_[x]=-~_[x])).sort((a,b)=>_[a]<_[b]).map(x=>console.log(x+':'+_[x]))

Выход:

a:2
31:1
This:1
is:1
text:1
and:1
number:1

Вы можете изменить _[a]и _[b]на _.aи _.b. Кроме того, изменения /\w+/g,_={}в _=/\w+/gбудет производить тот же результат.
eithed

@eithedog Спасибо! Тем не менее, я не могу изменить , _[a]чтобы быть , _.aпотому что он пытается получить доступ к свойству "a"из _, а не собственности a.
Зубная щетка

ах, правильно - порядок не будет сохранен. Продолжайте :)
Eed

О, я не заметил твой ответ ... мило. Но .. Object.keysстановится глобальным в ES6? Ваш ответ, кажется, предполагает это, но я не припоминаю, чтобы это было запланировано для ES6.
FireFly

@FireFly Я не могу найти никакой документации, но она отлично работает в Firefox. Я не проверял это в Chrome / Opera / IE.
Зубная щетка

3

Groovy 77 82

изменено регулярное выражение с [^\w]+на [^\d\p{L}]+для решения проблемы с подчеркиванием

String s = 'This is a text and a number: 31'

def a=s.split(/[^\d\p{L}]+/) 
a.collectEntries{[it, a.count(it)]}.sort{-it.value}

без первой строки, 82 символа

выход:

[a:2, This:1, is:1, text:1, and:1, number:1, 31:1]

nu_berне буквенно-цифровой. Это будет 2 слова
Cruncher

Зачем использовать nu_berвместо number?
Кевин Феган

Меня вводили в заблуждение некоторые другие сообщения;) Теперь я удалил «_» из входных данных, но исправил регулярное выражение для его обработки
Камил Миколайчик

3

GNU awk + coreutils: 71 69

gawk 'BEGIN{RS="\\W+"}{c[$0]++}END{for(w in c)print c[w],w}'|sort -nr

Хотя gawk asortработает на ассоциативных массивах, он, очевидно, не сохраняет значения индекса, что требует внешнегоsort

printf "This is a text and a number: 31." | 
gawk 'BEGIN{RS="\\W+"}{c[$0]++}END{for(w in c)print c[w],w}'|sort -nr
2 a
1 This
1 text
1 number
1 is
1 and
1 31

GNU awk 4.x: 100 93

Несколько большее, но чистое решение gawk, используемое PROCINFOдля установки порядка сортировки по умолчанию для ассоциативного массива (кажется, требует относительно недавнего gawk -> 4.x?)

BEGIN{RS="\\W+";PROCINFO["sorted_in"]="@val_num_desc"}
{c[$0]++}
END{for(w in c)print c[w],w}

Oooooh. Я не знал о PROCINFO. Как будто мне нужно другое оправдание, чтобы использовать awk в моей жизни. Проклинаю тебя!
dmckee

@dmckee TBH Я не знал о PROCINFO, пока не начал ковыряться - я был убежден, что должен быть способ сделать сортировку изначально - просто жаль, что идентификаторы такие длинные;)
steeldriver

В старые добрые времена пути просто не было. Что приводит к таким вещам, как мой старый ответ .
dmckee

-1. Подчеркивание _не должно быть включено в слово.
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

3

Javascript - 132 126 символов!

(Кратчайший код JS)

o={},a=[]
for(i in s=s.split(/[\W_]+/))o[z=s[i]]=o[z]+1||1
for(j in o)a.push([j,o[j]])
a.sort(function(b,c){return c[1]-b[1]})

Улучшено регулярное выражение и некоторые правки.


Ungolfed

s = s.split(/[\W_]+/), o={}, a=[]; // split along non-char letters, declare object and array

for (i in s) { n = s[i]; o[n] = o[n] + 1 || 1 } // go through each char and store it's occurence

for (j in o) a.push( [j, o[j]] ); // store in array for sorting

a.sort(function (b, c){ return c[1] - b[1]; }); // sort !

<= // make s = "Какой блестящий день, не так ли?"

=> [['is', 3],
['How', 1],
['блестящий', 1],
['this', 1],
['day', 1],
['isn', 1] ,
['t', 1]]


Старый - 156 143 141 140 132 символов

s=s.split(/[^\w]+/g),o={}
for(i in s){n=s[i];o[n]=o[n]+1||1}a=[]
for(j in o)a.push([j,o[j]])
a.sort(function(b,c){return c[1]-b[1]})

Дали первую попытку в гольф. Обратная связь приветствуется.


2

EcmaScript 6, 115 100 87 (без подсказок и предупреждений)

Благодаря @eithedog:

s.match(/\w+/g,a={}).map(w=>a[w]=-~a[w]),keys(a).map(w=>[w,a[w]]).sort((a,b)=>b[1]-a[1])

С подсказкой и предупреждением (100):

prompt(a={}).match(/\w+/g).map(w=>a[w]=-~a[w]);alert(keys(a).map(w=>[w,a[w]]).sort((a,b)=>b[1]-a[1]))

Запустите его в Firefox.


1
Вам не нужно var . Кроме того , вы можете перемещаться a={}внутри prompt- prompt(a={}). Вы также можете оставить Object.и изменить w=>a[w]=a[w]+1||1наw=>a[w]=-~a[w]
eithed

Очень хорошо. Теперь
превосходит

То же, что и для ответа @ toothbrush - перемещение объявления aиз приглашения в регулярное выражение сэкономит еще два символа.
eithed

Это красиво и чисто. Отличная работа!
Зубная щетка

-1. Подчеркивание _не должно быть включено в слово.
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

2

Руби 58 82 65

h=Hash.new 0
gets.scan(/[\d\w]+/){h[$&]+=1}
p *h.sort_by{|k,v|-v}

Тестовый забег:

$ ruby counttext.rb <<< "This is a text and a number: 31."
["a", 2]
["text", 1]
["This", 1]
["is", 1]
["and", 1]
["number", 1]
["31", 1]

Edit 58-> 80: Хорошо, я был далеко. Я забыл отсортировать слова по появлению. Также,Array#uniq не является перечислителем, но использует данный блок для сравнения элементов, поэтому передача putsего не отфильтровывает дубликаты (не то, что это говорит о том, что мы должны).


1
Может split(/\W+/)вместо scan(не проверено)?
Говард

@ Говард Спасибо. \Wисключает, _так что это должно было быть исправлено, но он все еще сохранял 2 символа (затем я добавил 20, чтобы исправить сортировку, которой я пренебрегал).
Даньеро

Не должны быть отсортированы вreverse (a=gets.split(/[_\W]+/)).uniq.map{|w|[w,a.count(w)]}.sort_by(&:last).reverse.map{|x|p x}
Эдуард Флоринеску

@EduardFlorinescu Нах. reverseслишком многословен;) Кстати, это несправедливо менять вопрос.
Даниеро

Если вы видите в выходном примере, он был отсортирован по убыванию только, что я забыл указать его.
Эдуард Флоринеску

2

F # - 169

let f s=(s+"").Split(set s-set(['a'..'z']@['A'..'Z']@['0'..'9'])|>Set.toArray)|>Seq.where((<>)"")|>Seq.countBy id|>Seq.sortBy((~-)<<snd)|>Seq.iter((<||)(printfn"%s:%d"))

Degolfed:

let count (s : string) =
    s.Split (set s - set (['a'..'z']@['A'..'Z']@['0'..'9']) |> Set.toArray)
 |> Seq.where ((<>) "")
 |> Seq.countBy id
 |> Seq.sortBy ((~-) << snd)
 |> Seq.iter ((<||) (printfn "%s:%d"))

Вывод при вызове из ФСИ:

> "This is a text and a number: 31." |> f
a:2
This:1
is:1
text:1
and:1
number:1
31:1
val it : unit = ()

Обновление: некоторые пояснения в соответствии с просьбой в комментариях.

Использует функции set для генерации массива не буквенно-цифровых символов на входе для передачи в String.Split, затем использует функции последовательности для фильтрации пустых строк, генерации количества слов и печати результата.

Некоторые приемы игры в гольф: добавляет пустую строку к аргументу функции s, чтобы заставить вывод типа аргумента в виде строки, а не явно объявлять тип. Использует Seq.where вместо Seq.filter для сохранения нескольких символов (они являются синонимами). Смешивает прямую трубу и обычные функции приложения в попытке минимизировать символы. Использует каррирование и (op) синтаксис для обработки <> ~ - и <|| операторы как обычные функции, чтобы избежать объявления лямбда-фильтра для фильтрации пустых строк, сортировки по убыванию количества и печати кортежей.


Вы должны обязательно вставить какое-то объяснение; Таким образом, мы можем понять ваш код.
Джастин

Добавлена ​​версия с дегольфедом и некоторые пояснения.
mattnewport

2

Python - 95 (сейчас 87 благодаря @primo)

d=__import__('re').findall(r'\w+',raw_input())
print sorted(map(lambda y:(y,d.count(y)),d))

Пример ввода:

'This is a text and a number: 31'

Образец вывода:

[('This', 1),('is', 1), ('a', 2),('text', 1),('and', 1),('a', 2),('number', 1),('31', 1)]

Любое улучшение sugestion будет оценено


1
Решение хорошее, но вывод не отсортирован.
Эдуард Флоринеску

Что вы имеете в виду под сортировкой? Спасибо за комментарий.
Azwr

1
\w Матчи [a-zA-Z0-9_] . Все ваши регулярные выражения могут быть заменены на r'\w+'. Кроме того, xпеременная не нужна, просто используйте raw_input()в качестве второго параметра для findall.
Прим

Под сортировкой OP подразумевается, что слова, которые появляются чаще всего, должны быть перечислены первыми. Кроме того, ваша программа должна включать printутверждение (то есть print map(...), иначе это не полная программа.
Примо

У меня нет времени, чтобы разобраться в этом прямо сейчас :( Я спешу, спасибо за предложения и комментарии.
Azwr

2

JavaScript 160 144 (отредактировано: для удовлетворения требований)

f=Function;o={};s.replace(/\w+/g,f('a','o[a]=++o[a]||1'));Object.keys(o).sort(f('b,c','return o[c]-o[b]')).map(f('k','console.log(k+" "+o[k])'))

Unminified:

f=Function;
o = {};
s.replace(/\w+/g, f('a','o[a]=++o[a]||1'));
Object.keys(o).sort(f('b,c', 'return o[c]-o[b]')).map(f('k','console.log(k+" "+o[k])'))

Регистрирует каждое слово в консоли по порядку, передавая следующую строку:

s="This is sam}}ple text 31to test the effectiveness of this code, you can clearly see that this is working-as-intended, but you didn't doubt it did you?.";

Выходы:

you 3
this 2
is 2
can 1
text 1
31to 1
test 1
the 1
effectiveness 1
of 1
This 1
code 1
sam 1
ple 1
clearly 1
see 1
that 1
working 1
as 1
intended 1
but 1
didn 1
t 1
doubt 1
it 1
did 1 

У меня нет сердца, чтобы использовать alert().


1
Сортировка должна быть по номеру. случаев так youдолжно быть первым.
Эдуард Флоринеску

@EduardFlorinescu Глупый я ... Я исправлю это позже.
Джордж Райт

@EduardFlorinescu исправлено
Джордж Райт

-1. Подчеркивание _не должно быть включено в слово.
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

++o[a]||1 => -~o[a]
l4m2

2

к [71 символ]

f:{s:" ",x;`_k!m@k:|(!m)@<.:m:#:'=`$1_'(&~((),/:s)like"[a-zA-Z0-9]")_s}

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

пример

f "This is a text and a number: 31."
a     | 2
31    | 1
number| 1
and   | 1
text  | 1
is    | 1
This  | 1

пример

f "won't won won-won"
won| 4
t  | 1

2

Javascript (135)

u=/\w+/g
for(i=s.length;i--;)for(w in a=s.match(u))u[w=a[w]]=u[w]||a.reduce(function(p,c){return p+=w==c},0)==i&&!console.log(w+":"+i)

Unminified:

u=/\w+/g;for (i=s.length;i--;)
    for(w in a=s.match(u))
        u[w=a[w]] = u[w] || 
           a.reduce(function(p,c){return p+=w==c},0)==i && !console.log(w+":"+i)

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

Примечания: оповещение уменьшило бы длину. Строго говоря, буквенно-цифровой должен быть[^\W_]


2

Haskell (153 = 104 кода + 49 импорт)

Довольно прямолинейная, полностью составленная функция ... никаких аргументов даже не требуется! Это мой первый гольф, так что иди спокойно, может быть? :)

import Data.Char
import Data.List
import Data.Ord
so=reverse.(sortBy$comparing snd).(map(\t@(x:_)->(x,length t))).group.sort.(map$filter isAlphaNum).words

Выход:

*Main> so "This is a text and a number: 31."
[("a",2),("text",1),("number",1),("is",1),("and",1),("This",1),("31",1)]

2

q (50)

desc count each group" "vs ssr[;"[^0-9A-Za-z]";" "]
  • ssr заменяет не буквенно-цифровые
  • "" vs разбивает результат в список символов
  • count каждая группа count создает dict, сопоставляющий различные элементы списка с количеством вхождений
  • desc сортирует dict по убыванию значений

редактировать: исправлено случайное совпадение ascii 58-64 и 91-96


1
Я не знаю, qно [0-z]основано ли регулярное выражение на ASCII? Если это так, не будет ли он также включать символы ASCII 58-64? Потому что это так : ; < = > ? @.
jimbobmcgee

Отличный улов jimbob, спасибо
nightTrevors

Пожалуйста; только заметил, потому что я нашел то же самое в C #. К сожалению, то же самое [A-z], что соответствует ASCII 91-96, которые являются `[\] ^
_`

Ах да, хороший маленький урок Ascii прямо здесь!
nightTrevors

Я только что обнаружил [^_\W]+для себя, что должно быть «исключить несловарные символы и подчеркивание» , если ваш синтаксис поддерживает \Wкласс ...
jimbobmcgee

2

Pure Bash (без внешних программ), 164

Это дольше, чем я надеялся, но я хотел посмотреть, можно ли провести необходимый подсчет и сортировку (в правильном направлении) исключительно с bashмассивами (ассоциативными и неассоциативными):

declare -A c
for w in ${@//[[:punct:]]/ };{ ((c[$w]++));}
for w in ${!c[@]};{ i=${c[$w]};((m=i>m?i:m));s[$i]+=$w:;}
for((i=m;i>0;i--));{ printf "${s[i]//:/:$i
}";}

Сохраните как файл сценария chmod +xи запустите:

$ ./countoccur Это текст и число: 31.
а: 2
и: 1
номер 1
текст: 1
31: 1
является: 1
Это: 1
$ 

2

AWK

awk -vRS='[^A-Za-z0-9]' '$0{c[$0]++}END{for(i in c)print c[i]"\t"i": "c[i]|"sort -nr|cut -f2-"}'

Делает работу без расширений:

$ echo 'This is a text and a number: 31.' | awk -vRS='[^A-Za-z0-9]' '$0{c[$0]++}END{for(i in c)print c[i]"\t"i": "c[i]|"sort -nr|cut -f2-"}'
a: 2
This: 1
text: 1
number: 1
is: 1
and: 1
31: 1

Если вместо этого вывести «count: word», это будет немного короче, но я хотел бы подражать выводу данного примера ...



1

Python 2.X (108 символов)

print'\n'.join('{}:{}'.format(a,b)for a,b in __import__("collections").Counter(raw_input().split()).items())

Python 3.X (106 символов)

print('\n'.join('{}:{}'.format(a,b)for a,b in __import__("collections").Counter(input().split()).items())

Separators will be anything that is not alpha-numeric - Вы только разделены на пробелы.
Даниеро

1

Haskell - 137

import Data.List
count text=let textS=(words(text\\".-\':")) in (sortBy (\(_,n) (_,m) -> compare m n)).nub$map(\t->(t,(length.(filter(==t)))textS)) textS

Не соответствует условию, что не алфавитно-цифровой должен быть разделитель.
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

1

Питон 3 - 76

Требование разделения на не алфавитно-цифровые символы, к сожалению, расширяет код на 19 символов. Вывод следующего показан правильно. Если вы не уверены, добавьте .most_common()после .Counter(...).

i=__import__
print(i('collections').Counter(i('re').findall('\w+',input())))

В / Output

Учитывая вклад This is a text and a number: 31. вы получаете следующий вывод:

Counter({'a': 2, 'is': 1, 'This': 1, 'and': 1, '31': 1, 'number': 1, 'text': 1})

Я пробовал это с другими значениями, такими как

1 2 3 4 5 6 7 8 2 1 5 3 4 6 8 1 3 2 4 6 1 2 8 4 3 1 3 2 5 6 5 4  2 2 4 2 1 3 6

чтобы убедиться, что порядок вывода не зависит от значения / хэша ключа. Этот пример производит:

Counter({'2': 8, '3': 6, '1': 6, '4': 6, '6': 5, '5': 4, '8': 3, '7': 1})

Но, как я уже сказал, print(i('collections').Counter(i('re').findall('\w+',input())).most_common())вернул бы результаты как определенно упорядоченного списка кортежей.


Python 3 - 57 (если пробела будет достаточно для разбиения: P)

print(__import__('collections').Counter(input().split()))

Если вы предполагаете, что строка находится в некоторой переменной s, как и в некоторых других ответах, вы можете потерять 6 символов, заменив input ().
Фил Х

@PhilH хорошо. Вы правы, но я бы никогда не прочитал это из требований. конечно, «string for JavaScript» -part может предложить это, но я не могу, с чистой совестью, интерпретировать строковую переменную как допустимый «вход». Но ты прав. это сократило бы это еще больше. :П
Дэйв Дж

-1. Подчеркивание _не должно быть включено в слово.
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

Ну, это зависит от определения буквенно-цифровой. В Python "\ w" определен для принятия буквенно-цифровых символов. Возможно, вы правы, но с такой интерпретацией правил мое решение остается верным. :)
Dave J
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.