AutoHotkey Community Forum Index AutoHotkey Community
Wir helfen uns gegenseitig aus der Patsche
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Wörter splitten zählen sortieren

 
This forum is locked: you cannot post, reply to, or edit topics.   This topic is locked: you cannot edit posts or make replies.    AutoHotkey Community Forum Index -> Ich brauche Hilfe!
View previous topic :: View next topic  
Author Message
garry



Joined: 25 Oct 2005
Posts: 891
Location: switzerland

PostPosted: Mon Dec 08, 2008 5:03 pm    Post subject: Wörter splitten zählen sortieren Reply with quote

In Fefe's Blog gefunden,
hat jemand Interesse ?
es muss nicht ahk sein (evtl thread verschieben)
mich würde aber die Lösung mit ahk interessieren
(ich passe wegen Inkompetenz)

kurz zusammengefasst, ein Program schreiben:
Quote:

-stdin lesen,
-in Wörter splitten,
-für die Wörter dann jeweils die Häufigkeit zählen,
-am Ende die Wörter mit Häufigkeiten nach letzteren sortiert ausgeben.
-Einfach genug, in perl ist das in unter 10 Zeilen ordentlich zu machen.


http://blog.fefe.de/?ts=b7c295e7

Beispielscripte in verschiedenen Sprachen
http://ptrace.fefe.de/wp/


Quote:
Sun Dec 7 2008

* [l] Ich mache gerade einen kleinen Test, bei dem ihr mir helfen könnt, wenn ihr Lust habt. Es geht darum, eine vergleichsweise triviale Aufgabenstellung in Skriptsprachen zu implementieren. Die Aufgabenstellung ist: stdin lesen, in Wörter splitten, für die Wörter dann jeweils die Häufigkeit zählen, am Ende die Wörter mit Häufigkeiten nach letzteren sortiert ausgeben. Einfach genug, in perl ist das in unter 10 Zeilen ordentlich zu machen.

Die Idee ist, dass man das in diversen Sprachen mal implementiert. Und zwar schon so, dass das nicht unnötig langsam abläuft, aber auch nicht groß performance-rumhacken. D.h.: in perl implementiert man das in perl und nicht als C-Extension. In C benutzt man malloc und stdio und keinen custom allocator bzw eigene I/O-Pufferverwaltung. Also schon versuchen, schnell ablaufenden Code zu schreiben, aber so, wie man das in der Sprache tun würde. Für C++ heisst das: STL und iostreams benutzen.

Am Ende kann man das natürlich nutzen, um da mal zu gucken, welche Implementation am schnellsten läuft. Hier geht es nicht darum, die Überlegenheit von C zu zeigen, sondern die relative Performance von Interpretern zu gucken. Es geht aber eben nicht nur um Performance, sondern der Code soll auch demonstrieren, wie man sowas in der jeweiligen Sprache löst. Damit man sich die Sourcen anschauen kann, und sich entscheiden kann, ob man diese Sprache für hinreichend elegant hält, dass man sich die mal näher anschauen will.

Wieso ihr mithelfen könnt: ich kann nicht alle Sprachen und habe auch keine Lust, mich da jetzt jeweils reinzugoogeln. Denn ich will den Sprachen ja auch gerecht werden und nicht bloss eine laufende Variante nehmen, die dann am Ende unfair schlecht aussieht oder unnötig langsam ist. Daher wäre es mir lieb, wenn mir jemand für die fehlenden Sprachen Sourcen zuschickt. Ich erwarte da jetzt nicht AppleScript oder so, aber C# wäre z.B. nett, und Tcl. Und vielleicht noch sowas wie LISP oder Scheme.

Hier sind die bisher existierenden Sourcen.
Back to top
View user's profile Send private message
IsNull



Joined: 20 Dec 2006
Posts: 3894
Location: Eidgenosse

PostPosted: Tue Dec 09, 2008 7:09 am    Post subject: Reply with quote

EDIT:
sodele: Very Happy


Mal ein Anfang Smile
Code:
str := "Main Name ist Haase, und ich weis von nix. Ich habe übrigens kein Auto, denn ich habe kein Geld. Wustest du das AHK sehr

lange Strings haben kann? Nix wie raus, ich komme gleich nach."

StringSplit, ARR, str, %a_space%, ?.`,`;

Loop, % ARR0   ;-------- zähle die Wörter:
{
   sWord := ARR%a_index%
   
   If(cnt%sWord% = ""){
      cnt%sWord% := 1
   }else{
      cnt%sWord% += 1
   }
}

Loop      ;sortiere die Wörter im Array
{
   change := false
   Loop, % ARR0
   {
      item1       := ARR%a_index%
      item1_cnt    := cnt%item1%
      POS_item1   := a_index
      Loop, % ARR0
      {
         item2       := ARR%a_index%
         item2_cnt    := cnt%item2%
      
         If(item1_cnt = item2_cnt){
            continue
         }else if (item1_cnt < item2_cnt){
            If(POS_item1 < a_index){
                ARRAY_SWAP("ARR",POS_item1,a_index)
                change := true
            }
         }else{
            If(POS_item1 > a_index){
                ARRAY_SWAP("ARR",POS_item1,a_index)
                change := true
            }
         }
      }
   }
   If(!change){
      break
   }
}


   ;---------------------- Ausgabe in MSGBOX, doppelte ignorieren

msg := "Wörter Vorkommen:`n----------------------------------`n"
Loop, % ARR0
{
   sWord := ARR%a_index%
   count := cnt%sWord%
   If(had_%sWord%){
      continue
   }
   had_%sWord% := true
   msg   .= sWord "`t`t"  count "`n"
}

msgbox % msg   



exitapp



ARRAY_SWAP(ARRAY,item1,item2){
global
   tmp_2        := %ARRAY%%item2%
   %ARRAY%%item2% := %ARRAY%%item1%
   %ARRAY%%item1% := tmp_2
   return
}


Cool


code lässt sich natürlich noch optimieren, dass ist einfach mal so der erste Erguss von mir Very Happy
_________________
Anfänger Manuals
AHK 1.1 HowTos
securityvision
Moderator
Back to top
View user's profile Send private message
garry



Joined: 25 Oct 2005
Posts: 891
Location: switzerland

PostPosted: Tue Dec 09, 2008 8:01 am    Post subject: Reply with quote

Vielen Dank IsNull, funktioniert einwandfrei
habe nur gewusst dass ich mit arrays arbeiten sollte , aber wie ....
das erste script von Dir ,
hier FileRead, sortiert mit sort,xx,U
Code:
/*

-stdin lesen,
-in Wörter splitten,
-für die Wörter dann jeweils die Häufigkeit zählen,
-am Ende die Wörter mit Häufigkeiten nach letzteren sortiert ausgeben.
-Einfach genug, in perl ist das in unter 10 Zeilen ordentlich zu machen.

http://blog.fefe.de/?ts=b7c295e7

Beispielscripte in verschiedenen Sprachen
http://ptrace.fefe.de/wp/

*/


F1=%A_scriptdir%\test51.txt
F2=%A_scriptdir%\test52.txt
F3=%A_scriptdir%\test53.txt

ifexist,%F2%
   Filedelete,%F2%
ifexist,%F3%
   Filedelete,%F3%

E1=
(
Mein Name ist "Hase", und ich weiss von nix.Ich habe übrigens kein Auto, denn ich habe kein Geld.Wusstest du das AHK sehr lange Strings haben kann?Nix wie raus,ich komme gleich nach.
)

ifnotexist,%F1%
  Fileappend,%E1%,%F1%

;----------- begin -------------------------------
FileRead, V, %F1%
StringSplit, ARR, V, %a_space%,`"`! `?`.`,`;
Loop, % ARR0
   {
   sWord := ARR%a_index%
   If(cnt%sWord% = "")
      cnt%sWord% := 1
   else
      cnt%sWord% += 1
   }
Loop, % ARR0
   {
   sWord := ARR%a_index%
   count := cnt%sWord%
   Fileappend,%count%|%sword%`r`n,%F2%
   }
  str=
  FileRead, Str,%F2%
  Sort, Str, U                  ; U removes duplicates
  FileAppend, %Str%,%F3%
;----------------- end --------------------------------
run,%F3%
exitapp
Back to top
View user's profile Send private message
Obi-Wahn



Joined: 19 Apr 2006
Posts: 1470
Location: Wien

PostPosted: Tue Dec 09, 2008 8:27 am    Post subject: Reply with quote

Nette Idee. Hab mal meine Grauen Zellen auch etwas angestrengt:


Code:
AutoTrim, On
IfEqual, 0, 0, ExitApp
specc := ",.-;:_!§$%&/()=?{[]}\<>|^°"
FileRead, string, %1%
Loop, Parse, string, %A_Space%, %specc%
   {
   gcount ++
   Loop {
      If (T%A_Index% != "") AND (T%A_Index% = A_LoopField) {
         C%A_Index% ++
         Break
      } Else If (T%A_Index% = "") {
         T%A_Index% := A_LoopField
         C%A_Index% ++
         Counter ++
         If (StrLen(T%A_Index%) > longest) {
            longest := StrLen(T%A_Index%)
         }
         Break
      }
   }
}
Loop, %counter% {
   Loop, % (longest - StrLen(T%A_Index%) + 5) {
      spacer .= " "
   }
   output .= T%A_Index% spacer "...     " C%A_Index% "`n"
   spacer := ""
}

FileAppend, Ergebnis:`nFolgende Wörter kommen vor (%gcount% gesamt):`n`n%output%, *
ExitApp


Is auch noch nicht perfekt (manche sonderzeichen werden nicht entfernt, die sonderzeichen in der cmd.exe werden nicht korrekt dargestellt), aber ich denke, ausbaufähig...
Greets

EDIT:
BTW: ICh hab den auszug als text.txt genommen:
Quote:
Die Idee ist, dass man das in diversen Sprachen mal implementiert. Und zwar schon so, dass das nicht unnötig langsam abläuft, aber auch nicht groß performance-rumhacken. D.h.: in perl implementiert man das in perl und nicht als C-Extension. In C benutzt man malloc und stdio und keinen custom allocator bzw eigene I/O-Pufferverwaltung. Also schon versuchen, schnell ablaufenden Code zu schreiben, aber so, wie man das in der Sprache tun würde. Für C++ heisst das: STL und iostreams benutzen.

_________________
Garten ist eine Kunstnatur
Das Leben ist nicht fair. Es ist nur fairer als der Tod, das ist alles.
Codes @ SV.ch - Obi-Wahns neue Homepage
No Nick, No Code -> No Support
Back to top
View user's profile Send private message Visit poster's website
IsNull



Joined: 20 Dec 2006
Posts: 3894
Location: Eidgenosse

PostPosted: Tue Dec 09, 2008 8:31 am    Post subject: Reply with quote

obi-wahn, bei dir fehlt noch die Sortierung nach Häufigkeit. Das ist das mühsamste Wink
_________________
Anfänger Manuals
AHK 1.1 HowTos
securityvision
Moderator
Back to top
View user's profile Send private message
Obi-Wahn



Joined: 19 Apr 2006
Posts: 1470
Location: Wien

PostPosted: Tue Dec 09, 2008 8:47 am    Post subject: Reply with quote

Geh bitte, wer sortiert denn schon....
Chaos ist doch viel kreativer.

Aber von mir aus:


Code:
AutoTrim, On
IfEqual, 0, 0, ExitApp
specc := ",.-;:_!§$%&/()=?{[]}\<>|^°"
FileRead, string, %1%
Loop, Parse, string, %A_Space%, %specc%
   {
   Loop {
      If (T%A_Index% != "") AND (T%A_Index% = A_LoopField) {
         C%A_Index% ++
         Break
      } Else If (T%A_Index% = "") {
         T%A_Index% := A_LoopField
         C%A_Index% ++
         Counter ++
         Break
      }
   }
}
Loop, %counter%
   output .= "  " C%A_Index% "x erscheint das Wort '" T%A_Index% "'`n"
Sort, output
FileAppend, Ergebnis:`n`n%output%, *
ExitApp

_________________
Garten ist eine Kunstnatur
Das Leben ist nicht fair. Es ist nur fairer als der Tod, das ist alles.
Codes @ SV.ch - Obi-Wahns neue Homepage
No Nick, No Code -> No Support
Back to top
View user's profile Send private message Visit poster's website
derRaphael



Joined: 09 Jan 2008
Posts: 1556
Location: ~/.

PostPosted: Tue Dec 09, 2008 3:46 pm    Post subject: Reply with quote

Ergebnisse vom text zweiter Quote des ersten posts:



Code:
; dR's kurztripp.ahk
GoSub, MakeText
   Txt := RegExReplace(txt,"[^ a-zA-ZöäüÖÄÜß#\-\/\\]"," "), Txt := RegExReplace(txt,"(\n|\s)+"," ")
   Txt := RegExReplace(txt,"\r|^\s+|\s+$"), sRegEx := tRegEx := RegExReplace(txt,"\s","`n",cnt)
   Sort,sRegEx,U
   Loop, Parse, sRegEx,`n
   {
      A_Current := A_LoopField, A_Count := 0
      Loop,Parse,tRegEx,`n
         if (A_Current = A_LoopField)
            A_Count++
      _%A_Count% .= ((StrLen(_%A_Count%)>0) ? ", " : "") A_Current, o .= ((A_Index>1) ? "`n" : "") A_Count
   }
   Sort,o,NUR
   Loop,Parse,o,`n
      out .= ((A_Index>1) ? "`n" : "") A_LoopField " mal:`n`t" _%A_LoopField%
      
   MsgBOx % out
Return
; *****************************************************
MakeText:
txt=
(
Sun Dec 7 2008

* [l] Ich mache gerade einen kleinen Test, bei dem ihr mir helfen könnt, wenn ihr Lust habt. Es geht darum, eine vergleichsweise triviale Aufgabenstellung in Skriptsprachen zu implementieren. Die Aufgabenstellung ist: stdin lesen, in Wörter splitten, für die Wörter dann jeweils die Häufigkeit zählen, am Ende die Wörter mit Häufigkeiten nach letzteren sortiert ausgeben. Einfach genug, in perl ist das in unter 10 Zeilen ordentlich zu machen.

Die Idee ist, dass man das in diversen Sprachen mal implementiert. Und zwar schon so, dass das nicht unnötig langsam abläuft, aber auch nicht groß performance-rumhacken. D.h.: in perl implementiert man das in perl und nicht als C-Extension. In C benutzt man malloc und stdio und keinen custom allocator bzw eigene I/O-Pufferverwaltung. Also schon versuchen, schnell ablaufenden Code zu schreiben, aber so, wie man das in der Sprache tun würde. Für C++ heisst das: STL und iostreams benutzen.

Am Ende kann man das natürlich nutzen, um da mal zu gucken, welche Implementation am schnellsten läuft. Hier geht es nicht darum, die Überlegenheit von C zu zeigen, sondern die relative Performance von Interpretern zu gucken. Es geht aber eben nicht nur um Performance, sondern der Code soll auch demonstrieren, wie man sowas in der jeweiligen Sprache löst. Damit man sich die Sourcen anschauen kann, und sich entscheiden kann, ob man diese Sprache für hinreichend elegant hält, dass man sich die mal näher anschauen will.

Wieso ihr mithelfen könnt: ich kann nicht alle Sprachen und habe auch keine Lust, mich da jetzt jeweils reinzugoogeln. Denn ich will den Sprachen ja auch gerecht werden und nicht bloss eine laufende Variante nehmen, die dann am Ende unfair schlecht aussieht oder unnötig langsam ist. Daher wäre es mir lieb, wenn mir jemand für die fehlenden Sprachen Sourcen zuschickt. Ich erwarte da jetzt nicht AppleScript oder so, aber C# wäre z.B. nett, und Tcl. Und vielleicht noch sowas wie LISP oder Scheme.

Hier sind die bisher existierenden Sourcen.
)
return


Anlauf#1 - keine Std I/O untersützung - dafür hübsch formatiert
14 zeilen pures ahk - der rest vorbereitung & ausgabe

grüße
dR
_________________

    Alle Skripte, sofern nicht anders vermerkt, sind unter CC-BY freigegeben
Back to top
View user's profile Send private message Send e-mail
garry



Joined: 25 Oct 2005
Posts: 891
Location: switzerland

PostPosted: Thu Dec 11, 2008 1:04 pm    Post subject: Reply with quote

Vielen Dank für eure Beispiele
das mit den arrays und regex finde ich sehr interessant und für mich nicht einfach , versuche es mal zu lernen
( habe von Fefe (Felix) noch nichts gehört )
Back to top
View user's profile Send private message
derRaphael



Joined: 09 Jan 2008
Posts: 1556
Location: ~/.

PostPosted: Thu Dec 11, 2008 3:40 pm    Post subject: Reply with quote

evtl hilfts

Code:
; alles was NICHT leerzeichen, a bis z, umlaute und sz (groß klein wo angebracht),
; raute, minus, slash und backslash ist entfernen und durch leerzeichen ersetzen
; (negierte gruppe durch zirkumflex am anfang)
Txt := RegExReplace(txt,"[^ a-zA-ZöäüÖÄÜß#\-\/\\]"," ")

; verbliebene mehrfache leerzeichen, und zeilenumbrüche die hinereinander folgen
; durch einfache leerzeichen ersetzen
Txt := RegExReplace(txt,"(\n|\s)+"," ")

; wagenrücklauf (?), leerzeichen am anfang und ende rausschmeissen
Txt := RegExReplace(txt,"\r|^\s+|\s+$")

; zwei variablen anlegen und alle leerzeichen durch zeilenumbruch ersetzen
; cnt entspricht der anzahl der ersetzungen
sRegEx := tRegEx := RegExReplace(txt,"\s","`n",cnt)

; alle doppelten rauschschmeissen
Sort,sRegEx,U

; parse lauf 1
Loop, Parse, sRegEx,`n
{
   A_Current := A_LoopField                        ; aktuelles feld als kopie anlegen
   A_Count := 0                                    ; zähler initialisieren

   Loop,Parse,tRegEx,`n                            ; zweite unsortierte kopie parsen
      if (A_Current = A_LoopField)                 ; aktuelles feld in kopie?
         A_Count++                                 ; zähler erhöhen

   ; _N array mit aktuellem wert anlegen / erweitern und ggf komma einfügen
   _%A_Count% .= ((StrLen(_%A_Count%)>0) ? ", " : "") A_Current
   o .= ((A_Index>1) ? "`n" : "") A_Count          ; häufigkeiten merken
}

Sort,o,NUR                                         ; häufigkeiten sortieren

Loop,Parse,o,`n                                    ; parsen und _N-Array ausgabe formatieren
   out .= ((A_Index>1) ? "`n" : "") A_LoopField " mal:`n`t" _%A_LoopField%
   
MsgBOx % out
Back to top
View user's profile Send private message Send e-mail
garry



Joined: 25 Oct 2005
Posts: 891
Location: switzerland

PostPosted: Thu Dec 11, 2008 8:17 pm    Post subject: Reply with quote

Vielen Dank für die Erklärungen / Kommentare zum regex und die Beispiele mit den arrays / index , habe es gespeichert zum Lernen
Back to top
View user's profile Send private message
Display posts from previous:   
This forum is locked: you cannot post, reply to, or edit topics.   This topic is locked: you cannot edit posts or make replies.    AutoHotkey Community Forum Index -> Ich brauche Hilfe! All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group