Taschenrechner mit Stack
proc rpn {ausdruck} {
set stapel {}
foreach token $ausdruck {
switch -regexp -- $token {
{^-?[0-9]+(\.[0-9]+)?$} { lappend stapel $token }
{^[-+*/]$} {
set b [lindex $stapel end]
set a [lindex $stapel end-1]
set stapel [lrange $stapel 0 end-2]
lappend stapel [expr "$a $token $b"]
}
default { error "unbekanntes Token: $token" }
}
}
return [lindex $stapel 0]
}
puts [rpn {3 4 +}]
puts [rpn {5 1 2 + 4 * + 3 -}]
puts [rpn {10 4 /}]
puts [rpn {10 4.0 /}]
if {[catch {rpn {1 x +}} fehler]} { puts "Fehler: $fehler" }Ausgabe
7 14 2 2.5 Fehler: unbekanntes Token: x
Textstatistik
set text "Der Hund und die Katze. Die Katze und der Hund! Der Hund schläft."
set woerter [regexp -all -inline {[[:alpha:]]+} [string tolower $text]]
set zaehler [dict create]
foreach w $woerter { dict incr zaehler $w }
set paare {}
dict for {w n} $zaehler { lappend paare [list $w $n] }
set sortiert [lsort -index 0 [lsort -integer -decreasing -index 1 $paare]]
foreach p [lrange $sortiert 0 2] { puts "[lindex $p 0]: [lindex $p 1]" }
puts "Wörter gesamt: [llength $woerter], verschiedene: [dict size $zaehler]"
puts "Längstes Wort: [lindex [lsort -command {apply {{a b} {expr {[string length $b] - [string length $a]}}}} $woerter] 0]"Ausgabe
der: 3 die: 2 ft: 1 Wörter gesamt: 14, verschiedene: 7 Längstes Wort: katze
Primzahlen und Sieb
proc sieb {n} {
for {set i 2} {$i <= $n} {incr i} { set prim($i) 1 }
for {set i 2} {$i * $i <= $n} {incr i} {
if {$prim($i)} {
for {set j [expr {$i * $i}]} {$j <= $n} {incr j $i} { set prim($j) 0 }
}
}
set erg {}
for {set i 2} {$i <= $n} {incr i} { if {$prim($i)} { lappend erg $i } }
return $erg
}
puts [sieb 50]
puts [llength [sieb 1000]]Ausgabe
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 168
CSV lesen und auswerten
set csv "region,produkt,menge,preis\nNord,Apfel,10,1.20\nSued,Birne,5,0.80\nNord,Birne,8,0.80\nWest,Apfel,20,1.10"
set zeilen [split $csv "\n"]
set kopf [split [lindex $zeilen 0] ,]
set umsatz [dict create]
foreach z [lrange $zeilen 1 end] {
lassign [split $z ,] region produkt menge preis
if {![dict exists $umsatz $region]} { dict set umsatz $region 0 }
dict set umsatz $region [expr {[dict get $umsatz $region] + $menge * $preis}]
}
foreach r [lsort [dict keys $umsatz]] {
puts [format "%-5s %7.2f" $r [dict get $umsatz $r]]
}
puts "Spalten: [join $kopf { | }]"Ausgabe
Nord 18.40 Sued 4.00 West 22.00 Spalten: region | produkt | menge | preis
Mini-Testframework
set bestanden 0
set fehler 0
proc teste {name ausdruck erwartet} {
global bestanden fehler
if {[catch {uplevel 1 $ausdruck} ergebnis]} { set ergebnis "FEHLER: $ergebnis" }
if {$ergebnis eq $erwartet} {
incr bestanden
puts "ok $name"
} else {
incr fehler
puts "FEHLER $name (erhalten: $ergebnis, erwartet: $erwartet)"
}
}
teste addition {expr {1 + 2}} 3
teste string {string toupper abc} ABC
teste liste {lsort {c a b}} {a b c}
teste absichtlich {expr {2 * 2}} 5
puts "$bestanden bestanden, $fehler fehlgeschlagen"Ausgabe
ok addition ok string ok liste FEHLER absichtlich (erhalten: 4, erwartet: 5) 3 bestanden, 1 fehlgeschlagen
Merke
- Tcl eignet sich für Werkzeuge: Rechner, Textauswertung, CSV, Mini-Frameworks
switch -regexp,regexp -all -inlineunddict incrsind häufige Bausteinelassignundlsort -indexmachen Tabellenverarbeitung bequemuplevelerlaubt eigene Test- und Kontrollbefehle
Aufgabe
Erweitere den RPN-Rechner um ** und sqrt.