Ich muss einige Daten mit einem alten, im Haus entwickelten Algorithmus komprimieren/dekomprimieren. Dort habe ich viele Operationen wie:Bitstream-Bibliothek in Scala
if the next bit is 0 take the following 6 Bits and interpret them as an Int
if the next bits are 10 take the following 9 Bits and interpret them as an Int
etc.
Kennt jemand so etwas wie ein „Bitstrem“ Klasse in Scala? (Ich habe nichts gefunden und hoffe, dass ich es nicht selbst implementieren musste.)
Dank
Edit: ich die Antwort mit http://www.scala-lang.org/node/8413 kombiniert („The Architecture of Scala Sammlungen“) If jemand muss die Samething:
abstract class Bit
object Bit {
val fromInt: Int => Bit = Array(Low, High)
val toInt: Bit => Int = Map(Low -> 0, High -> 1)
}
case object High extends Bit
case object Low extends Bit
import collection.IndexedSeqLike
import collection.mutable.{Builder, ArrayBuffer}
import collection.generic.CanBuildFrom
import collection.IndexedSeq
// IndexedSeqLike implements all concrete methods of IndexedSeq
// with newBuilder. (methods like take, filter, drop)
final class BitSeq private (val bits: Array[Int], val length: Int)
extends IndexedSeq[Bit]
with IndexedSeqLike[Bit, BitSeq]
{
import BitSeq._
// Mandatory for IndexedSeqLike
override protected[this] def newBuilder: Builder[Bit, BitSeq] =
BitSeq.newBuilder
//Mandatory for IndexedSeq
def apply(idx: Int): Bit = {
if(idx < 0 || length <= idx)
throw new IndexOutOfBoundsException
Bit.fromInt(bits(idx/N) >> (idx % N) & M)
}
}
object BitSeq {
// Bits per Int
private val N = 32
// Bitmask to isolate a bit
private val M = 0x01
def fromSeq(buf: Seq[Bit]): BitSeq = {
val bits = new Array[Int]((buf.length + N - 1)/N)
for(i <- 0 until buf.length) {
bits(i/N) |= Bit.toInt(buf(i)) << (i % N)
}
new BitSeq(bits, buf.length)
}
def apply(bits: Bit*) = fromSeq(bits)
def newBuilder: Builder[Bit, BitSeq] = new ArrayBuffer mapResult fromSeq
// Needed for map etc. (BitSeq map {:Bit} should return a BitSeq)
implicit def canBuilderFrom: CanBuildFrom[BitSeq, Bit, BitSeq] =
new CanBuildFrom[BitSeq, Bit, BitSeq] {
def apply(): Builder[Bit, BitSeq] = newBuilder
def apply(from: BitSeq): Builder[Bit, BitSeq] = newBuilder
}
}
Dank. Aber ich habe Probleme zu verstehen: "(0 /: ii) ((i, b) => (i << 1) | b)" Speziell die "(0 /: ii)". /: ist das FoldLeft. Das würde sich also in "(0.Folgende (ii))" übersetzen? (Wo ist mein Mystake?) – Fabian
Es übersetzt eigentlich 'ii.foldLeft (0)'. Ein Operator, der mit einem Doppelpunkt endet, wird als eine Methode für sein _right_-Argument interpretiert statt dessen! Was die Falte sagt, ist, gegeben ein Akkumulator "i" und ein neues Bit "b", das Ergebnis (i << 1) | b, das heißt, verschiebe "i" um ein Bit nach links und setze das neue bisschen unten. Die Faltung wendet dies über den gesamten Iterator an. –