www.jammni.de

Logo - Kleiner Drache
Login
Username:

Passwort:

Daten merken
Auto-Login
Registrieren
 
Online
niemand
 
Forumsuche
Suche nach:

Logo - DracheHaskell-Forum

SteRly

Gepostet:
23.11.2012 20:15

anzElement liefert die Anzahl des Auftretes eines gegebenen Elements in einer Liste  
Hallo, in der Überschrift seht ihr schon meine Aufgabe, die wir u. a. aufbekommen haben.
Ich habe grade mal 90 Minuten mit Haskell gearbeitet und soll nun mit den drei Dingen diese Aufgabe lösen:
1) rekursiv mit Musteranpassung
2) rekursiv ohne Musteranpassung (guards)
3) mit Akkumulatortechnik

Also ich habe bisher das:
-- anzElement (Zählt die Anzahl von x bzw y in Liste xs)
-- rekursiv
anzElement :: Int -> [Int] -> Int
anzElement x [] = 0
anzElement x (y:xs) | x == y = 1 + anzElement x xs -- hier y!
| x /= y = anzElement x xs

-- rekursiv mit guards
anzElement2 x xs | null xs = 0
| x == head xs = 1 + anzElement x (tail xs)
| x /= head xs = anzElement x (tail xs)

-- Akku
anzElement3 x xs = anzElement3\' x xs 0
anzElement3\' y (x:xs) akku = anzElement3\' x xs (akku+1)
anzElement3\' y [] akku = akku


Alles bis auf das mit dem Akku funktioniert..
Könnt ihr mir helfen?

Liebe Grüße
Sterly
Zum Seitenanfang    
 
IKT

Gepostet:
23.11.2012 21:35

   
Wenn ich das richtig sehe, hast du in der 2. Zeile der Def. von anzElement3 vergessen darauf zu prüfen, ob y == x oder nicht, oder?
Zum Seitenanfang    
 
Landei

Gepostet:
23.11.2012 23:22

   

anzElement3 x xs = anzElement3\' x xs 0
anzElement3\' y (x:xs) akku = anzElement3\' y xs (akku + (fromEnum (x == y)))
anzElement3\' y [] akku = akku


Dabei wandelt fromEnum Aufzählungstypen (wie hier Bool) in Zahlen um, ist also kürzer für if x == y then 1 else 0

Die kürzeste Lösung für diese Aufgabe wäre wohl


anzElement4 x = length . filter (==x)


Willkommen in der wunderbaren Welt von Haskell :-)
Zum Seitenanfang    
 
IKT

Gepostet:
24.11.2012 09:05

   
Ist die schönere Lösung eigentlich genau so effizient wie die anderen lösungen, d.h. wird beim Compilieren das zusätzliche Durchlaufen der Liste \'wegoptimiert\'?
Zum Seitenanfang    
 
Landei

Gepostet:
24.11.2012 11:18

   
Ich denke nicht. Ein guter Kompromiss zwischen Lesbarkeit und Performance wäre ein Fold:


anzElement5 x xs = foldr f 0 xs where
f y n = n + (fromEnum (x==y)))


Ich wundere mich sowieso, wieso es kein count :: (a -> Bool) -> [a] -> Int im Prelude gibt.
Zum Seitenanfang    
 
SteRly

Gepostet:
26.11.2012 17:06

   
Hallo ihr Lieben,

danke für euren schnellen Antworten, dass wir x == y machen müssten, war uns bewusst, aber irgendwie gibt dann Haskell eine Fehlermeldung aus:
anzElement3 x xs = anzElement3\' x xs 0
anzElement3\' y (x:xs) akku = y == x = anzElement3\' y (x xs)(akku+1)
anzElement3\' y [] akku = akku


Fehlermeldung:
2.hs:2:37: parse error on input `=\'


Irgendwie verzweifle ich :(
Zum Seitenanfang    
 
Landei

Gepostet:
26.11.2012 20:06

   
Die Syntax stimmt nicht. Ihr könnt Guards verwenden, dann muss in der zweiten Zeile das erste = durch | ersetzt werden. Allerdings fehlt euch dann immer noch der Fall einer nicht-leeren Liste mit y != x. Oder ihr verwendet ein ganz normales if-then-else.
Zum Seitenanfang