Порахуйте слова в тексті та покажіть їх


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буде 2 різних слова від wouldn't.

Напишіть найкоротший код своєю мовою.

Найкоротша правильна відповідь поки:


5
Чи має значення випадок (тобто Thisте саме, що thisі tHIs)?
— Гарет

Якщо щось, що не буквено-цифрове, вважається роздільником, це wouldn't2 слова ( wouldnі t)?
— Гарет

@Gareth Слід враховувати великі регістри, Thisі thisце справді два різні слова, те саме wouldnі t.
— Едуард Флорінеску

Якби не було 2 слів, чи не повинні бути "Були б" і "НТ", оскільки його коротке слово "Не хотів би", чи це дуже багато граматиків наци-іш?
— Теун Пронк

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

Відповіді:


27

греп і основні  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
@Tomas: додав це до відповіді, дякую. Я залишив захист зірочки, тому що вона розширювала назви файлів у деяких оболонках.
— Тор

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()));}

Безголівки:

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 був розроблений з позначень, з наміром, що як і математика, лаконічне позначення звільняє вас чітко мислити. Знову ж таки, як математика, коли ви вперше бачите це позначення, ви схильні вважати, що це зовсім не зрозуміло, але мови завжди здаються складними для початку. Хоча було б легше, якби все не було на одній лінії, хоча ...
— Phil H

що б ви не придумали в 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 111c 115c 118c 114c 113c

(через LINQPad в режимі "C # Заяви", не включаючи рядок введення)

Версія 1: 142c

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();

Безголівки:

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: 114c

( [\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();

Безголівки:

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 char

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.
— djhurio

6

perl6: 49 символів

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

Розчісуйте введення для відповідності матеріалів \w+, покладіть отриманий список слів в а Bag, запитайте їх пари та сортуйте їх за від’ємним значенням. (The *є Безвідносно зірка, це не множення тут)

вихід:

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

3
Перл 6 мене лякає.
— примо

1
Кожен раз, коли я думаю про класну особливість мови, я шукаю її, і вона знаходиться десь у Perl6. Тому це займає багато часу ...
— Phil H

Можна обрізати 6 символів, використовуючи .wordsзамість .comb(/\w+/):)
— Mouq

@Mouq: на жаль, .wordsне знімає :або .з введення, як потрібно :(
— Айко

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

6

Пітон 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
— Начімота

4
-split"\W+"узгодження порожнього рядка між останнім .і кінцем рядка; також \W+поєдинки, _які технічно заборонено
— jimbobmcgee

4

Перл 69

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

Додано рекомендації від @primo та @protist


1
А що з сортуванням?
— daniero

@daniero, чудовий момент! Це зараз сортує!
— Дом Гастінгс

1
Я думаю, що це настільки ж лаконічно, як це може вийти. Якщо ви не заперечуєте про попередження про депресію, між geі між ними не залишається пробіл for. Також <=>оператора можна замінити на -.
— прим

2
@primo Ahhh -замість <=>геніального, не впевнений, що це на підказках з гольфу для нитки Perl. Я оновлю це пізніше, дякую!
— Дом Гастінгс

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

4

Потужність: 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дасть» такий же результат.
— вийшов

@eithedog Дякую! Тим НЕ менше, я не можу змінити , _[a]щоб бути , _.aтому що він намагається отримати доступ до властивості "a"з _, а не власні a.
— Зубна щітка

ах, правильно - порядок не зберігатиметься. Продовжуйте :)
— eithed

О, я не помітив вашої відповіді .. приємно. Але .. 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?
— Кевін Феган

Мені були введені в оману деякі інші повідомлення;) тепер я видалив "_" із вхідних даних, але виправив регулярний вираз, щоб обробити його
— Kamil Mikolajczyk

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}

Ооооо. Я не знав про 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]})

Покращено регулярне вираження та деякі зміни.


Безумовно

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 = "Як блискучим є цей день, не є"

=> [['є', 3],
['Як', 1],
['блискучий', 1],
['цей', 1],
['день', 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

Дуже хороша. Зараз б'є робочий Python :)
— teh_senaus

Те саме, що і у відповіді @ зубної щітки - переміщення декларації aвід підказок до regexp прибере ще два символи.
— вийшов

Це приємно і чисто. Хороша робота!
— Зубна щітка

-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]

Редагувати 58-> 80: Гаразд, я пішов. Я забув сортувати слова за випадками. Крім того, Array#uniqне є нумератором, але використовує заданий блок для порівняння елементів, тому перехід putsдо нього не фільтрував дублікати (не те, що він говорить, що ми повинні).


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

@Howard Спасибі \Wвиключає _так, що довелося виправити, але він все-таки зберег 2 символи (тоді я додав 20, щоб виправити сортування, яким я знехтував).
— daniero

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

@EduardFlorinescu Nah. reverseє занадто багатослівним;) Btw, це нечесно міняти питання.
— daniero

Якщо ви бачите у вихідному зразку, він був відсортований за походженням, тільки я забув його вказати.
— Едуард Флорінеску

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"))

Дегольф:

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"))

Вихідні дані при виклику з fsi:

> "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 = ()

Оновлення: Деякі пояснення, як вимагається в коментарях.

Використовує встановлені функції для створення масиву не алфавітно-цифрових символів на вході для переходу до String.Split, потім використовує функції послідовності для фільтрації порожніх рядків, генерації підрахунків слів та друку результату.

Деякі прийоми з гольфу: додає порожній рядок до аргументу функції s, щоб примусити виводити аргумент як рядок, а не явно декларувати тип. Для збереження кількох символів використовується Seq.where, а не Seq.filter (вони є синонімами). Змішує передню трубу та звичайну функціональну програму, намагаючись мінімізувати символи. Використовує currying і (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)]

Буде вдячний будь-який поліпшення застосувань


1
Рішення добре, але вихід не сортується.
— Едуард Флорінеску

Що ви маєте на увазі під сортуванням? Дякуємо за коментар
— Azwr

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

Впорядковано, ОП означає, що слова, які найчастіше з’являються, потрібно перелічити першими. Крім того, ваша програма повинна містити printзаяву (тобто print map(...), інакше це не повна програма.
— прим

Я зараз не
— встигаю

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])'))

Без обмежень:

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]
— l4м2

2

k [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)

Без обмежень:

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 замінює не буквено-цифрові
  • "" Розбиває результат на список символів
  • підрахунок кожної групи підрахунків створює дікт, що відповідає різним елементам списку з кількістю випадків
  • desc сортує дікт за низхідними значеннями

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


1
Я не знаю, qале на основі регексу [0-z]ASCII? Якщо це так, чи не включатиме він символи ASCII 58-64? Тому що це : ; < = > ? @.
— jimbobmcgee

Чудовий лов джимбоб, спасибі
— 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.
a: 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- Ви розділяєте лише пробіли.
— daniero


1

Пітон 3 - 76

Вимога розщеплення на не алфавітно-цифрові символи, на жаль, розширює код на 19 знаків. Вихід із наведеного нижче відображається правильно. Якщо ви не впевнені, додайте .most_common()після .Counter(...).

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

Вхід / Вивід

З огляду на вхід, 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 може запропонувати його, але я не можу з чистою совістю інтерпретувати строкову змінну як дійсний "input". Але ви праві. це зменшило б її ще більше. : P
— Дейв J

-1. Підкреслення _не повинно входити в слово.
— n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

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