Aufgabe 12.3: Buchstaben zählen

Disclaimer: Dieser Thread wurde aus dem alten Forum importiert. Daher werden eventuell nicht alle Formatierungen richtig angezeigt. Der ursprüngliche Thread beginnt im zweiten Post dieses Threads.

Aufgabe 12.3: Buchstaben zählen
Kann mir jemand einen Tipp geben, wie ich beim d) Teil aus der Rückgabe der streamCount Funktion, die Häufigkeit der Buchstaben rausziehen kann? Also das Int aus Stream[(Char,Map[Char, Int])]. Komm ich da irgendwie mit .apply ran?


das geht bestimmt mit fold map :slight_smile:


EDIT: (Angabe falsch verstanden, Post darf ignoriert werden)

Ich bin gerade ebenfalls bei der d). Die Idee ist ja, das man quasi einen “Stream im Stream” zurückgibt, sprich das Stream.take(1) einen Stream zurückliefert und Stream.take(3) ebenfalls, aber einen anderen. Genau das versuche ich gerade zu realisieren, allerdings meckert bei mir Eclipse mit der Fehlermeldung “type mismatch; found : scala.collection.immutable.Stream[(Char, Int)] required: (Char, Int)”.

Würde ich hier jetzt aber direkt einen Stream mit den entsprechenden Tupeln zurückgeben, so ergäbe das ja keinen Sinn - ich will mit contAbsCount(“Kuehe machen Muehe”.toStream).take(10).toList ja schließlich nicht den Stream der eigentlichen Ergebnistupel einschränken ((K, 1), (u, 1) usw.), sondern ja nur bis zur Position x im Original-Eingabeparameter-Stream zählen.

Meine Hilfs-Stream-Funktion hat übrigens die Form (streamCount(…).(…).toStream) #:: Hilfsfunktion(x)). i ist jeweils ausgelassener Code, da das Posten von Quellcode ja eher nicht erwünscht ist[/i]

Ich habe auch schon versucht, die Funktion verschiedenst umzsuchreiben - dann meckert der Interpreter mit java.util.NoSuchElementException: head of empty stream.


Siehe vorherige Post. Außer ich verstehe die Aufgabe falsch …

1 Like

Auf die Rückgabe kann ich problemlos zugreifen. Ich nehme quasi die Rückgabe und nutze dann .toStream - aus irgendwelchen Gründen akzeptiert Eclipse aber gerade das nicht, da ich ja eigentlich in der Hilfsfunktion keinen erneuten Stream sondern Tupel in der Form von (Char, Int) zurückliefern muss. Würde ich dann aber quasi auf das nächste Element des eigentlichen Streams (also von countAbsCount(Stream)) zugreifen, benötige ich aber wieder einen “komplett anderen” Stream, da sich die absoluten Häufigkeiten der Buchstaben ja schließlich verändert haben.

EDIT: Angabe jetzt verstanden, Aufgabe jetzt deutlich einfacher.

Was vielleicht noch nützlich sein könnte:

http://stackoverflow.com/questions/7604000/basic-scala-hashmap-return-types-are-ignored

Ich habe im Übrigen auch apply genutzt, um die Buchstabenhäufigkeiten an der jeweiligen Position abzurufen.


Hmm, ich bekomme das mit dem map und apply nicht hin. Hab jetzt schon alle möglichen Variationen versucht, bekomme aber auch immer eine head of empty stream Meldung :frowning: Vielleicht könnte jemand so nett sein und die Lösung zur d) nach der Abgabefrist posten :slight_smile:


Bei mir krachts auch immer mit der Meldung „head of empty stream“ …


Kleiner Tipp: Bei der d) darf der Stream (zumindest so wie ich das sehe) nicht mit .tail o.ä. “beschnitten” werden. Stattdessen muss die aktuelle Position durchgereicht werden. (Sprich: Die Parameterliste von contAbsCountHelper ist nicht gleich mit der von contAbsCount, sondern noch um eine Art Iterator erweitert - andernfalls können auch bei der Methode streamCount die vorherigen Buchstaben nicht mitgezählt werden). Vielleicht liegt euer Fehler auch an der “Top-Down”-Denkweise, bei Streams muss (wenn ich das richtig verstanden) habe immer Bottom-Up gearbeitet werden.


Verwendest du denn irgendwo explizit .head? Wenn du es mit map machst, ist das denke ich nicht unbedingt notwendig.

Man kann statt m.apply(a) auch einfach m(a) schreiben :wink:


hallo zusammen.

Ich hab die d) jetzt endlich gelöst:

also prinzipiell muss man grob so vorgehen.

man erstellt sich ein val x das man mit streamCount füllt

das x steckt man dann in eine helper funktion.

In der helper funktion nutze ich head und tail

zuerst head auf x um das erste element zu holen, auf die tupel entsprechend zugreifen und
dann noch eine stream verbindung #:: mit dem tail von x und schon läuft es


Dankeschön hedge!
Jetzt hab ich’s auch endlich hinbekommen :slight_smile: Find das ganz schön verwirrend mit den Streams von Tupeln, von einer Map von Tupeln … :scared:


Ich bin nah dran, bekomme aber folgenden Fehler beim Laden, und hab solche Fehler schon öfter bekommen und will mal wissen was das bedeutet :

Was bedeutet das Option ? Also: Option[Int] ?

Der Fehler taucht auf wo ich eben, nun ja,
dingsbums #:: rekursiverAufruf
habe, das Fehlerzeichen zeigt dann auf den Verkettungsoperator.

NACHTRAG: War wohl ein klassisches Programmierentenproblem. Ich musste erst jemanden fragen um dann selber auf die Lösung zu kommen.
Ich hab halt auf ner Map get() gemacht und das liefert eben so ein Option[dingsbums] zurück. Dementsprechend muss dann im hinteren Teil von #::
auch son Ding drin sein. Wenn man aber vorne statt get() apply() macht, funktionierts.


EDIT: habe deinen beitrag nicht richtig gelesen und den Nachtrag übersehen


Wär jemand so nett und könnte noch den Code für den d) Teil mit Verwendung von map auf den Stream posten? Hab das Ganze nur mit Helper geschafft :\


hier sind mal 3 mögliche Versionen:

val m = streamCount(sc, MapChar, Int)

//Version 1
m.map(x => (x._1, x._2(x._1)))
//Version 1

//Version 2
for(x ← m) yield (x._1 , x._2(x._1 ))
//Version 2

//Version 3
def helper: Stream[(Char, Map[Char, Int])] => Stream[ (Char, Int) ] = m => (m.head._1,m.head._2(m.head._1))#::helper(m.tail)

helper(m)
//Version 3


Top! Vielen Dank für die schnelle Antwort :slight_smile:


[quote=[hedgehogs dilemma = 42]]
hier sind mal 3 mögliche Versionen:

val m = streamCount(sc, MapChar, Int)

//Version 1
m.map(x => (x._1, x._2(x._1)))
//Version 1

//Version 2
for(x ← m) yield (x._1 , x._2(x._1 ))
//Version 2
[/quote]

Aus eigener Erfahrung würde ich zu Version 1 raten.
Habe es bei den Bonusaufgaben wie Version 2 mit for-comprehension implementiert und da wurde mir angekreidet, dass es für unendliche Streams ungeeignet ist, da der Speicher schnell knapp werden könnte.