Zähle die Wörter in einem Text und zeige sie an

26

Der Code sollte einen Text enthalten (nicht obligatorisch können alle Dateien, Stdins, Strings für JavaScript usw. sein):

This is a text and a number: 31.

Die Ausgabe sollte die Wörter mit der Anzahl ihrer Vorkommen enthalten, sortiert nach der Anzahl der Vorkommen in absteigender Reihenfolge:

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

Beachten Sie, dass 31 ein Wort ist, ein Wort also eine alphanumerische Zahl ist. Zahlen fungieren nicht als Trennzeichen, sodass sie beispielsweise 0xAFals Wort qualifiziert sind. Trennzeichen sind alles, was nicht alphanumerisch ist, einschließlich .(Punkt) und -(Bindestrich), i.e.oder pick-me-upführen zu 2 bzw. 3 Wörtern. Sollte zwischen Groß- und Kleinschreibung unterschieden werden Thisund thiszwei verschiedene Wörter sein, 'würde dies auch ein Trennzeichen sein wouldnund t2 verschiedene Wörter aus sein wouldn't.

Schreiben Sie den kürzesten Code in der Sprache Ihrer Wahl.

Kürzeste richtige Antwort bisher:

Eduard Florinescu
quelle
5
Ist der Fall wichtig (dh ist Thisderselbe wie thisund tHIs)?
Gareth
Wenn nicht-alphanumerische Zeichen als Trennzeichen gelten, sind es wouldn't2 Wörter ( wouldnund t)?
Gareth
@Gareth Sollte zwischen Groß- und Kleinschreibung unterscheiden Thisund thisin der Tat zwei verschiedene Wörter sein, dasselbe wouldnund t.
Eduard Florinescu
Wenn nicht 2 Wörter wären, sollte es nicht "Would" und "nt" sein, da es die Abkürzung für Would not ist, oder ist das zu viel Grammer Nazi-ish?
Teun Pronk
@TeunPronk Ich versuche es einfach zu halten, ein paar Regeln setzen werden Ausnahmen fördern , um mit der Grammatik zu sein, und es gibt eine Menge von Ausnahmen aus there.Ex auf Englisch ist i.e.ein Wort, aber wenn wir alle die Punkte an der der Punkt lassen Das Ende der Sätze wird mit Anführungszeichen oder einfachen Anführungszeichen usw. angegeben.
Eduard Florinescu

Antworten:

27

grep und coreutils  44  42

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

Prüfung:

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

Ergebnisse in:

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

Aktualisieren

  • Verwenden Sie die Option ohne Berücksichtigung der Groß- und Kleinschreibung und kürzeren regulären Ausdruck. Vielen Dank, Tomas.
Thor
quelle
2
Dies ist fast genau McEllroys Antwort auf Knuths Buch Literate Programming . Der einzige Unterschied besteht darin, dass dies keine Pipe headam Ende enthält.
AJMansfield
Das war so ziemlich mein erster Gedanke.
Rob
1
Würde '\ w +' nicht auch funktionieren?
Sylwester
1
41 Zeichen :grep -io \[A-Z0-9]*|sort|uniq -c|sort -nr
Tomas
1
@Tomas: Fügte dies zur Antwort hinzu, danke. Ich habe im Schutz für das Sternchen gelassen, weil es Dateinamen in einigen Shells erweitert hat.
Thor
18

Java 8: 289

Das ist ziemlich gut, da Java eine sehr nicht golfende Sprache ist.

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

Führen Sie von der Befehlszeile aus:

java -jar wordCounter.jar This is a text and a number: 31.
AJMansfield
quelle
Falscher regulärer Ausdruck zum Teilen. Es sollte sein"[^\\W_]"
n̴̖̋h̷͉̃ã̷͉h̷̭̿d̷̰̀ĥ̷̳
Bei n̴̖̋h̴̖̋ã̷͉h̷̭̿d̷̰̀ĥ̷̳ nimmt die String.split(String regex)Methode ein Muster, das mit dem Trennzeichen übereinstimmt , auf das aufgeteilt werden soll. So "aababba".split("b")würde zum Beispiel das Array ergeben {"aa", "a", "", "a"}. Mein regulärer Ausdruck [^\\w\\d]bedeutet "ein Zeichen weder in der Wortzeichen- noch in der Ziffernzeichenklasse". [^\\W_]ist stattdessen 'ein Zeichen, das weder ein Unterstrich ist noch in der Klasse der Nicht-Wortzeichen enthalten ist' und würde mit jedem Wortzeichen außer dem Unterstrich übereinstimmen.
AJMansfield
Entschuldigung, mein vorheriger Kommentar war falsch. \wenthält \d, \dist also überflüssig. \wenthält einen Unterstrich, der je nach Fragestellung als Trennzeichen zu betrachten ist. Also sollte der richtige reguläre Ausdruck für das Teilen sein "[\\W_]+".
n̴̖̋h̴̖̋a̷̭̿h̷̭̿d̸̡̅ẗ̵̨́
@ n̴̖̋h̴̖̋ã̷͉h̷̭̿d̷̰̀ĥ̷̳ ok, danke; Ich habe das Problem behoben.
AJMansfield
17

APL (57)

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

z.B

      ⎕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

Erläuterung:

  • ⎕D,⎕A,⎕UCS 96+⍳26: Zahlen, Großbuchstaben, Kleinbuchstaben
  • (I←⍞)∊: Eingabe lesen, speichern in I , welche alphanumerisch sind
  • Z←I⊂⍨: Iin alphanumerische Zeichengruppen aufgeteilt, speichern inZ
  • +⌿∘.≡⍨Z: für jedes Element in Z Sehen Sie , wie oft es auftritt
  • Z,⍪: stimmen mit jedem Element in überein Z paarweise der Häufigkeit zu, mit der es auftritt
  • G←⊃∪↓: Wählen Sie nur die eindeutigen Paare aus, in denen gespeichert werden soll G
  • ⍒,1↓⍉G: Erhalte sortierte Indizes für die Vorkommen
  • G[... ;]: ordne die Zeilen Gnach den angegebenen Indizes
Marinus
quelle
6
was ... die ... f .....
Ozh
6
Deshalb habe ich Albträume.
Thebluefish
3
@Thebluefish: APL wurde aus einer Notation entwickelt, mit der Absicht, dass Sie ähnlich wie in Mathematik mit einer präzisen Notation klar denken können. Ähnlich wie in der Mathematik denken Sie, wenn Sie diese Notation zum ersten Mal sehen, dass sie überhaupt nicht klar ist, aber die Sprachen erscheinen anfangs immer komplex. Es wäre einfacher, wenn nicht alles in einer Zeile
Phil H
Was auch immer Ihnen in APL einfällt, ich sehe nur Unicode-Müll, Richtungspfeile und eine verkehrte Kiefer. das ist schlimmer als J
Be
Könnte kürzer sein mit ⎕s( help.dyalog.com/latest/Content/Language/System%20Functions/… ) und dem neuen Key Operator ( 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

(über LINQPad im Modus "C # -Anweisungen", ohne Eingabezeichenfolge)

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

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

Ergebnisse:

Ergebnisse

Version 2: 114c

( [\w]beinhaltet _, was falsch ist !; [A-z]beinhaltet [ \ ] ^ _ `; sich niederlassen auf [^_\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

Ergebnisse: (als Version 1)

jimbobmcgee
quelle
Übrigens, für Version 2 stimmt Ihre ungolfed-Version nicht mit Ihrer golfed-Version überein. Und da Sie wörtliche Zeichenfolgen verwenden, können Sie schreiben@"[^_\W]"
n̴̖̋h̴̖̋ã̷͉h̷̭̿d̸̡̅ẗ̵̨́
@ n̴̖̋h̴̖̋ã̷͉h̷̭̿d̷̰̀ĥ̷̳ - Tippfehler behoben und das zusätzliche `` zum Speichern eines Zeichens entfernt - danke !!
Jimbobmcgee
7

R, 58 char

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

Verwendung:

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 
Plannapus
quelle
Dies ist kürzer (49 Zeichen) sort(table(gsub("[[:punct:]]","",scan(,""))),d=T). Leider funktionieren beide Lösungen für nicht richtig wouldn't.
Djhurio
6

perl6: 49 zeichen

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

Durchkämmen Sie die Eingabe, um die Übereinstimmungen zu ermitteln \w+, fügen Sie die Ergebnisliste der Wörter in ein ein Bag, fragen Sie nach deren Paaren und sortieren Sie sie nach negativen Werten. (Das *ist ein Was auch immer Stern, es ist hier keine Multiplikation)

Ausgabe:

"a" => 2
"This" => 1
"is" => 1
"text" => 1
"and" => 1
"number" => 1
"31" => 1
Ayiko
quelle
3
Perl 6 macht mir Angst.
Primo
1
Jedes Mal, wenn ich an ein cooles Sprachfeature denke, suche ich danach und es ist irgendwo in Perl6. Aus diesem Grund dauert es lange ...
Phil H
Sie können 6 Zeichen .words.comb(/\w+/)
abschneiden,
@Mouq: Entfernt .wordsdas :oder nicht .wie erforderlich von der Eingabe :(
Ayiko
-1. _sollte nicht in einem Wort unter der Problemstellung enthalten sein.
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)

Funktioniert jetzt mit newline:

$ 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
daniero
quelle
Dies funktioniert nicht, wenn der Text Zeilenumbrüche oder mehr als ein Leerzeichen enthält.
klingt.net
@ klingt.net behoben.
Daniero
6

PHP - 84 Bytes

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

Eingabe wird als Kommandozeilenargument akzeptiert, zB:

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

Ausgabe für die Beispielzeichenfolge:

Array
(
    [a] => 2
    [number] => 1
    [31] => 1
    [and] => 1
    [text] => 1
    [is] => 1
    [This] => 1
)
primo
quelle
1
es heißt, die Eingabe ist das, was Sie wollen. So können Sie es als Befehlszeilenparameter mit$argv[1]
Einacio 29.01.14
@Einacio guten Anruf.
Primo
-1. Der Unterstrich _sollte nicht in einem Wort enthalten sein.
n̴̖̋h̷͉̃a̷̭̿h̷̭̿d̷̰̀ĥ̷̳
@ n̴̖̋h̴̖̋ã̷͉h̷̭̿d̷̰̀ĥ̷̳ behoben.
Primo
5

PowerShell (40)

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

$ s ist eine Variable, die die Eingabezeichenfolge enthält.

mikrobisch
quelle
2
[\W]ist nicht gut genug - es stimmt mit einem Leerzeichen in meinem Test überein. Und es ist nicht nach absteigender Anzahl geordnet ...
jimbobmcgee
$s -split"[\W]"|group -ca|where{$_.Name -ne ""}|sort{-$_.Count}bringt dich näher (natürlich
kostenpflichtig
Hoppla, ich habe den Sortierteil verpasst. Ich werde meine Antwort in Kürze korrigieren.
Mikrobier
alternativ:$s -split"\W+"|group -ca |sort count -des
Nacimota
4
-split"\W+"stimmt mit einer leeren Zeichenfolge zwischen dem letzten .und dem Ende der Zeichenfolge überein; auch \W+Spiele, _die technisch nicht erlaubt ist
jimbobmcgee
4

Perl 69

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

Empfehlungen von @primo und @protist hinzugefügt

Dom Hastings
quelle
1
Was ist mit Sortieren?
Daniero
@daniero, exzellenter Punkt! Das sortiert jetzt!
Dom Hastings
1
Ich denke, das ist so knapp wie es nur geht. Wenn Sie keine Warnung vor Verfall haben, ist zwischen geund kein Leerzeichen erforderlich for. Auch der <=>Operator kann durch ersetzt werden -.
Primo
2
@primo Ahhh -statt <=>ist genial, nicht sicher, ob das auf den Golftipps für Perl-Thread steht. Ich werde dies später aktualisieren, danke!
Dom Hastings
1
Hey @protist, \wenthält auch Zahlen ( perl -e 'print for"a 1 2 3 4 b"=~/\w/g'Drucke a1234b), aber Ihr Mechanismus zum Wiederholen der Wörter speichert ein anderes Zeichen, sodass ich es aktualisiere. Vielen Dank!
Dom Hastings
4

Powershell: 57 55 53 62 57

(ohne Eingabezeichenfolge)

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

kehrt zurück:

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}

(mit Requisiten an @microbian für Gruppe -ca)

jimbobmcgee
quelle
3

EcmaScript 6

Version 1 (108 Zeichen)

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

Version 2 (102 Zeichen)

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

Version 3 (105 Zeichen)

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

Version 4 (94 Zeichen)

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

Version 5 (ohne Alarm; 87 Zeichen)

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

Version 6 (100 Zeichen)

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

Ausgabe:

a:2
31:1
This:1
is:1
text:1
and:1
number:1
Zahnbürste
quelle
Sie können _[a]und _[b]zu _.aund ändern _.b. Wenn Sie auch auf ändern /\w+/g,_={}, _=/\w+/gwird das gleiche Ergebnis erzielt.
Eithed
@eithedog Danke! Ich kann es jedoch nicht ändern _[a], _.ada versucht wird, auf die Eigenschaft "a"von _und nicht auf die Eigenschaft zuzugreifen a.
Zahnbürste
Ah, richtig - die Reihenfolge wird nicht eingehalten.
Machen
Oh, ich habe deine Antwort nicht bemerkt ... nett. Aber .. wird Object.keysein globaler in ES6? Ihre Antwort scheint dies anzunehmen, aber ich kann mich nicht erinnern, dass dies für ES6 geplant war.
FireFly
@FireFly Ich kann keine Dokumentation finden, aber es funktioniert gut in Firefox. Ich habe es nicht in Chrome / Opera / IE getestet.
Zahnbürste
3

Groovy 77 82

geändert regulärer Ausdruck [^\w]+zu , [^\d\p{L}]+um Problem mit Unterstrich zu lösen

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}

ohne erste Zeile 82 Zeichen

Ausgabe:

[a:2, This:1, is:1, text:1, and:1, number:1, 31:1]
Kamil Mikolajczyk
quelle
nu_berist nicht alphanumerisch. Dies sollten 2 Wörter sein
Cruncher
Warum nu_berstatt verwenden number?
Kevin Fegan
Ich wurde von einigen anderen Posts irregeführt;) Jetzt habe ich das "_" aus der Eingabe entfernt, aber den regulären Ausdruck korrigiert, um damit umzugehen
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

Obwohl gawk asortmit assoziativen Arrays gearbeitet wird, werden die Indexwerte anscheinend nicht beibehalten, sodass das Externe erforderlich istsort

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

Eine etwas größere, aber reine Gawk-Lösung, mit PROCINFOder die Standardsortierreihenfolge für das assoziative Array festgelegt wird (erfordert anscheinend ein relativ neues Gawk -> 4.x?)

BEGIN{RS="\\W+";PROCINFO["sorted_in"]="@val_num_desc"}
{c[$0]++}
END{for(w in c)print c[w],w}
Stahlfahrer
quelle
Oooooh. Ich wusste nichts über PROCINFO. Als ob ich eine weitere Ausrede brauchte, um awk in meinem Leben zu benutzen. Verfluche dich!
dmckee
@dmckee TBH ich wusste nicht , über procinfo , bis ich um begann Stossen - Ich war dort überzeugt hatte ein Weg , um die Art nativ zu tun - nur schade , die Kennungen so lang sind;)
steeldriver
In den schlechten alten Zeiten gab es einfach keinen Weg. Was zu Dingen wie dieser alten Antwort von mir führt .
dmckee
-1. Der Unterstrich _sollte nicht in einem Wort enthalten sein.
n̴̖̋h̷͉̃a̷̭̿h̷̭̿d̷̰̀ĥ̷̳
3

Javascript - 132 126 Zeichen!

(Kürzester JS-Code)

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

Der reguläre Ausdruck und einige Änderungen wurden verbessert.


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 = "Wie glänzend dieser Tag ist, ist nicht"

=> [['is', 3],
['How', 1],
['shiny', 1],
['this', 1],
['day', 1],
['isn', 1] ,
['t', 1]]


Alt - 156 143 141 140 132 Zeichen

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

Gab einen ersten Versuch beim Golfen. Feedback erwünscht.

Gaurang Tandon
quelle
2

EcmaScript 6, 115 100 87 (ohne Aufforderung und Warnung)

Vielen Dank an @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])

Mit Aufforderung und Alarm (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]))

Führen Sie es in Firefox aus.

teh_senaus
quelle
1
Das brauchst du nicht var . Sie können sich auch a={}in prompt- bewegen prompt(a={}). Drop Sie können auch Object.und ändern w=>a[w]=a[w]+1||1zuw=>a[w]=-~a[w]
Eithed
Sehr schön. Schlägt das funktionierende Python jetzt :)
teh_senaus
Das Gleiche gilt für die Antwort von @ atoothbrush: Wenn Sie die Deklaration von prompt auf regexp verschieben, sparen Sie zwei weitere Zeichen.
Eithed
Es ist schön und sauber. Gut gemacht!
Zahnbürste
-1. Der Unterstrich _sollte nicht in einem Wort enthalten sein.
n̴̖̋h̴̖̋a̷̭̿h̷̭̿d̷̰̀ĥ̷̳
2

Ruby 58 82 65

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

Testlauf:

$ 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: Ok, ich war weit weg. Ich habe vergessen, die Wörter nach Vorkommen zu sortieren. Außerdem Array#uniqist es kein Enumerator, sondern verwendet einen bestimmten Block, um Elemente zu vergleichen, sodass bei der Übergabe putsan diesen Block keine Duplikate herausgefiltert wurden (nicht, dass darin angegeben ist, dass wir dies tun sollen).

daniero
quelle
1
Vielleicht split(/\W+/)statt scan(ungetestet)?
Howard
@ Howard Danke. \Wschließt _damit aus, dass behoben werden musste, aber es wurden trotzdem 2 Zeichen gespeichert (dann habe ich 20 hinzugefügt, um die Sortierung zu korrigieren, die ich vernachlässigt hatte).
Daniero
Sollte nicht sortiert werden reverse (a=gets.split(/[_\W]+/)).uniq.map{|w|[w,a.count(w)]}.sort_by(&:last).reverse.map{|x|p x}
Eduard Florinescu
@EduardFlorinescu Nah. reverseist viel zu wortreich;) Übrigens ist es nicht fair, die Frage zu ändern.
Daniero
Wenn Sie im Ausgabebeispiel sehen, wurde es absteigend sortiert, nur dass ich vergessen habe, es anzugeben.
Eduard Florinescu
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"))

Entgolfet:

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

Ausgabe bei Aufruf von 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 = ()

Update: Einige Erklärungen wie in den Kommentaren angefordert.

Verwendet Set-Funktionen, um ein Array nicht-alphanumerischer Zeichen in der Eingabe zu generieren, die an String.Split übergeben werden sollen. Anschließend werden mit Sequenzfunktionen leere Zeichenfolgen herausgefiltert, Wortzahlen generiert und das Ergebnis gedruckt.

Einige Golf-Tricks: Fügt dem Funktionsargument s eine leere Zeichenfolge hinzu, um die Typinferenz des Arguments als Zeichenfolge zu erzwingen, anstatt den Typ explizit zu deklarieren. Verwendet Seq.where anstelle von Seq.filter, um einige Zeichen zu speichern (sie sind Synonyme). Mischt Forward Pipe und normale Funktionsanwendung, um Zeichen zu minimieren. Verwendet currying und (op) -Syntax, um <> ~ - und <|| zu behandeln Operatoren als reguläre Funktionen, um zu vermeiden, dass Lambdas deklariert werden, um leere Zeichenfolgen zu filtern, nach absteigender Anzahl zu sortieren und Tupel zu drucken.

mattnewport
quelle
Sie sollten auf jeden Fall eine Erklärung einfügen; Auf diese Weise können wir Ihren Code verstehen.
Justin
Hinzugefügt eine entgolfte Version und eine Erklärung.
Mattnewport
2

Python - 95 (jetzt 87 dank @primo)

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

Beispieleingabe:

'This is a text and a number: 31'

Beispielausgabe:

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

Verbesserungsvorschläge sind willkommen

Azwr
quelle
1
Die Lösung ist schön, aber die Ausgabe ist nicht sortiert.
Eduard Florinescu
Was meinst du mit sortiert? Danke für den Kommentar.
29.
1
\wStreichhölzer [a-zA-Z0-9_]. Ihre gesamte Regex kann durch ersetzt werden r'\w+'. Außerdem wird die xVariable nicht benötigt, sondern nur raw_input()als zweiter Parameter verwendet findall.
Primo
Nach Sortierung bedeutet das OP, dass die Wörter, die am häufigsten vorkommen, zuerst aufgelistet werden müssen. Außerdem sollte Ihr Programm eine printAnweisung (dh print map(...) enthalten, da es sonst kein vollständiges Programm ist.
Primo
Ich habe
momentan
2

JavaScript 160 144 (Bearbeitet: um Anforderungen zu erfüllen)

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

Nicht abgeschlossen:

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

Protokolliert jedes Wort der Reihe nach in der Konsole und übergibt die folgende Zeichenfolge:

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?.";

Ausgänge:

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 

Ich habe nicht das Herz zu gebrauchen alert().

George Reith
quelle
1
Die Sortierung sollte nach der Nummer erfolgen. von Vorkommen yousollte so zuerst sein.
Eduard Florinescu
@EduardFlorinescu Dumme mich ... Ich werde es später beheben.
George Reith
@EduardFlorinescu behoben
George Reith
-1. Der Unterstrich _sollte nicht in einem Wort enthalten sein.
n̴̖̋h̷͉̃a̷̭̿h̷̭̿d̷̰̀ĥ̷̳
++o[a]||1 => -~o[a]
14 m²,
2

k [71 Zeichen]

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

Alle anderen Zeichen außer alphanumerischen Zeichen werden als Trennzeichen betrachtet.

Beispiel

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

Beispiel

f "won't won won-won"
won| 4
t  | 1
Nyi
quelle
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)

Nicht abgeschlossen:

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)

Durchläuft jede mögliche Anzahl von Übereinstimmungen in absteigender Reihenfolge und gibt Wörter mit dieser Anzahl von Vorkommen aus. Nur um schrecklich zu sein.

Anmerkungen: Alarm hätte die Länge etwas reduziert. Genau genommen sollte alphanumerisch sein[^\W_]

Zachary Vance
quelle
2

Haskell (153 = 104 Code + 49 Import)

Ziemlich unkomplizierte, komplett komponierte Funktion ... kein Argument nötig! Dies ist mein erstes Golfspiel. :)

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

Ausgabe:

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

q (50)

desc count each group" "vs ssr[;"[^0-9A-Za-z]";" "]
  • ssr ersetzt nicht alphanumerisch
  • "" vs teilt das Ergebnis in eine Symbolliste auf
  • count Jede Gruppenzählung erstellt ein Dikt, das bestimmte Elemente der Liste mit der Anzahl der Vorkommen vergleicht
  • desc sortiert das Diktat nach absteigenden Werten

edit: korrigiert versehentlich übereinstimmende ascii 58-64 und 91-96

nightTrevors
quelle
1
Ich habe keine Ahnung, qaber ist der Regex [0-z]ASCII-basiert? Wenn ja, würde es nicht auch ASCII-Zeichen 58-64 enthalten? Weil das so ist : ; < = > ? @.
Jimbobmcgee
Toller Fang jimbob, danke
nightTrevors
Bitte; nur entdeckt, weil ich das gleiche in c # gefunden habe. Traurig selbe mit [A-z], das ASCII 91-96 zusammenbringt, die `[\] ^ _` `sind
jimbobmcgee
Ah, du bist richtig, nette kleine Ascii-Lektion genau dort!
NightTrevors
Ich habe gerade [^_\W]+für mich entdeckt , dass "Nicht-Wort-Zeichen und Unterstrich ausschließen" sein sollte , wenn Ihre Syntax die \WKlasse unterstützt ...
Jimbobmcgee
2

Pure Bash (keine externen Programme), 164

Das ist länger als ich gehofft hatte, aber ich wollte sehen, ob das notwendige Zählen und Sortieren (in die richtige Richtung) nur mit bashArrays (assoziativ und nicht assoziativ) durchgeführt werden kann:

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
}";}

Als Skriptdatei speichern chmod +xund ausführen:

$ ./countoccur Dies ist ein Text und eine Nummer: 31.
a: 2
und 1
Nummer 1
Text 1
31: 1
ist: 1
Dies: 1
$ 
Digitales Trauma
quelle
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-"}'

Erledigt den Job ohne kitschige Erweiterungen:

$ 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

Wenn stattdessen "count: word" ausgegeben wird, ist dies etwas kürzer, aber ich wollte die angegebene Beispielausgabe nachahmen ...


quelle
1

Python 2.X (108 - Zeichen)

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

Python 3.X (106 - Zeichen)

print('\n'.join('{}:{}'.format(a,b)for a,b in __import__("collections").Counter(input().split()).items())
Abhijit
quelle
Separators will be anything that is not alpha-numeric - Sie teilen sich nur Leerzeichen.
Daniero
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
Landarzar
quelle
Erfüllt nicht die Bedingung, dass nicht-alphanumerisch als Trennzeichen verwendet werden soll.
n̴̖̋h̷͉̃a̷̭̿h̷̭̿d̷̰̀ĥ̷̳
1

Python 3 - 76

Das Erfordernis der Aufteilung auf nicht alphanumerische Zeichen erweitert den Code leider um 19 Zeichen. Die Ausgabe des Folgenden wird korrekt angezeigt. Wenn Sie sich nicht sicher sind, fügen Sie .most_common()nach dem ein hinzu .Counter(...).

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

Ein / Ausgabe

Angesichts der Eingabe von This is a text and a number: 31. Sie folgende Ausgabe:

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

Ich habe es mit anderen Werten wie versucht

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

um sicherzustellen, dass die Ausgabereihenfolge nicht vom Wert / Hash des Schlüssels abhängt. Dieses Beispiel erzeugt:

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

Aber wie gesagt, print(i('collections').Counter(i('re').findall('\w+',input())).most_common())würde das Ergebnis als eine definitiv geordnete Tupelliste zurückliefern .


Python 3 - 57 (wenn ein Leerzeichen zum Teilen ausreichen würde: P)

print(__import__('collections').Counter(input().split()))
Dave J
quelle
Wenn Sie annehmen, dass sich die Zeichenfolge in einigen Variablen befindet, wie dies auch bei anderen Antworten der Fall ist, können Sie durch Ersetzen von input () 6 Zeichen verlieren.
Phil H
@ PHILH gut. Sie haben recht, aber ich würde das nie aus den Anforderungen herauslesen. Sicher, der "String für JavaScript" -Teil könnte es vorschlagen, aber ich kann eine String-Variable nicht mit gutem Gewissen als gültige "Eingabe" interpretieren. Aber Sie haben Recht. das würde es noch mehr verkürzen. : P
Dave J
-1. Der Unterstrich _sollte nicht in einem Wort enthalten sein.
n̴̖̋h̷͉̃a̷̭̿h̷̭̿d̷̰̀ĥ̷̳
Nun, das hängt von der Definition von alphanumerisch ab. In Python ist "\ w" definiert, um alphanumerische Zeichen zu akzeptieren. Sie mögen Recht haben, aber bei dieser Art der Auslegung der Regeln ist meine Lösung immer richtig. :)
Dave J