Huffman code Assignment 4 KangPil Kim Jin Kim

  • Slides: 43
Download presentation
Huffman code Assignment 4 Kang-Pil Kim, Jin Kim

Huffman code Assignment 4 Kang-Pil Kim, Jin Kim

Ex) Huffman (a, l, s, c), 5 0 1 a, 2 (l, s, c),

Ex) Huffman (a, l, s, c), 5 0 1 a, 2 (l, s, c), 3 10 11 l, 1 List((s, 1), (c, 1), (l, 1), (a, 2) (s, c), 2 110 111 s, 1 c, 1

Code • abstract class Code. Tree • case class Fork( left: Code. Tree, right:

Code • abstract class Code. Tree • case class Fork( left: Code. Tree, right: Code. Tree, chars: List[Char], weight: Int) extends Code. Tree • case class Leaf(char: Char, weight: Int) extends Code. Tree

Code • def weight(tree: Code. Tree): Int = tree match { case Fork(_, _,

Code • def weight(tree: Code. Tree): Int = tree match { case Fork(_, _, _, w) => w case Leaf(_, w) => w } • def chars(tree: Code. Tree): List[Char] = tree match { case Fork(_, _, cs, _) => cs case Leaf(c, _) => List(c) }

Code • def make. Code. Tree(left: Code. Tree, right: Code. Tree) = Fork( left,

Code • def make. Code. Tree(left: Code. Tree, right: Code. Tree) = Fork( left, right, chars(left) : : : chars(right), weight(left) + weight(right)) (s, a), 2 s, 1 a, 1

Code • def string 2 Chars(str: String): List[Char] = str. to. List • def

Code • def string 2 Chars(str: String): List[Char] = str. to. List • def singleton(trees: List[Code. Tree]): Boolean = trees. size == 1

Code • def times(chars: List[Char]): List[(Char, Int)] = { // 빈도수 체크 후 Weight

Code • def times(chars: List[Char]): List[(Char, Int)] = { // 빈도수 체크 후 Weight value생성 def incr(acc: Map[Char, Int], c: Char) = { val count = (acc get c). get. Or. Else(0) + 1 acc + ((c, count)) } (Map[Char, Int]() /: chars)(incr). iterator. to. List } /: => foldleft List(“s”, ”c”, ”a”, ”l”, ”a”) Map((s, 1), (c, 1)) Map((s, 1)) Map() ‘s’ ‘c’

Fold. Left • (xs fold. Left Accumulate) (function) • ‘ 0’ for ‘+’ operator

Fold. Left • (xs fold. Left Accumulate) (function) • ‘ 0’ for ‘+’ operator • ‘ 1’ for ‘ *’ operator

Code • def make. Ordered. Leaf. List(freqs: List[(Char, Int)]): List[Leaf] = { freqs. sort.

Code • def make. Ordered. Leaf. List(freqs: List[(Char, Int)]): List[Leaf] = { freqs. sort. With((f 1, f 2) => f 1. _2 < f 2. _2) // 오름차순 정렬. map((f) => Leaf (f. _1, f. _2)) //각 리스트들의 원소들을 Leaf로 생성 }

Code • def combine(trees: List[Code. Tree]): List[Code. Tree] = trees match { case left

Code • def combine(trees: List[Code. Tree]): List[Code. Tree] = trees match { case left : : right : : cs => (make. Code. Tree(left, right) : : cs). sort. With((t 1, t 2) => weight(t 1) < weight(t 2)) case _ => trees } s, a, 2 s, 1 a, 1 l, 1 Nil

Code • def until(p: List[Code. Tree]=>Boolean, f: List[Code. Tree]=>List[Code. Tree]) // singleton //combine (trees:

Code • def until(p: List[Code. Tree]=>Boolean, f: List[Code. Tree]=>List[Code. Tree]) // singleton //combine (trees: List[Code. Tree]) : List[Code. Tree] = { } if (p(trees)) trees // if singleton is true else until(p, f)( f(trees) ) // else recursive until()

PATMAT “Scala” string 2 Chars create. Code. Tree quick. Encode convert encode. Bits List(1,

PATMAT “Scala” string 2 Chars create. Code. Tree quick. Encode convert encode. Bits List(1, 1, 0, 0) decode List(S, c, a, l, a)

create. Code. Tree (chars: List[Char]): Code. Tree def create. Code. Tree(chars: List[Char]): Code. Tree

create. Code. Tree (chars: List[Char]): Code. Tree def create. Code. Tree(chars: List[Char]): Code. Tree = { until(singleton, combine)( make. Ordered. Leaf. List(times(chars)) ). head } List(S, c, a, l, a) times List((S, 1), (c, 1), (a, 2), (l, 1)) make. Ordered. Leaf. List(Leaf(S, 1), Leaf(c, 1), Leaf(l, 1), Leaf(a, 2)) combine singleton until List( Fork(Leaf(a, 2), Fork(Leaf(l, 1), Fork(Leaf(S, 1), Leaf(c, 1), List(S, c), 2), List(l, S, c), 3), List(a, l, S, c), 5) )

create. Code. Tree (chars: List[Char]): Code. Tree Fork(List(a, l, S, c), 5) Leaf(a, 2

create. Code. Tree (chars: List[Char]): Code. Tree Fork(List(a, l, S, c), 5) Leaf(a, 2 ) Fork(List(l, S, c), 3) Leaf(l, 1 ) Fork(List(S, c), 2 ) Leaf(S, 1) Leaf(c, 1 )

create. Code. Tree (chars: List[Char]): Code. Tree chars: List[Char] Leaf(S, 1) Leaf(c, 1 )

create. Code. Tree (chars: List[Char]): Code. Tree chars: List[Char] Leaf(S, 1) Leaf(c, 1 ) Leaf(l, 1 ) Leaf(a, 2 ) nil

create. Code. Tree (chars: List[Char]): Code. Tree def until(. . ). . { if

create. Code. Tree (chars: List[Char]): Code. Tree def until(. . ). . { if (p(trees)) trees else until(p, f)( f(trees) ) } def combine(trees: List[Code. Tree])… = trees match { case left : : right : : cs => (make. Code. Tree(left, right) : : cs). sort. With((t 1, t 2) => weight(t 1) < weight(t 2)) case _ => trees } Fork(List(S, c), 2 ) Leaf(S, 1) Leaf(c, 1 ) Leaf(l, 1 ) Leaf(a, 2 ) nil

create. Code. Tree (chars: List[Char]): Code. Tree def until(. . ). . { if

create. Code. Tree (chars: List[Char]): Code. Tree def until(. . ). . { if (p(trees)) trees else until(p, f)( f(trees) ) } def combine(trees: List[Code. Tree])… = trees match { case left : : right : : cs => (make. Code. Tree(left, right) : : cs). sort. With((t 1, t 2) => weight(t 1) < weight(t 2)) case _ => trees } weight=2 Fork(List(S, c), 2 ) Leaf(S, 1) Leaf(c, 1 ) weight=1 Leaf(l, 1 ) weight=2 Leaf(a, 2 ) nil

create. Code. Tree (chars: List[Char]): Code. Tree def until(. . ). . { if

create. Code. Tree (chars: List[Char]): Code. Tree def until(. . ). . { if (p(trees)) trees else until(p, f)( f(trees) ) } def combine(trees: List[Code. Tree])… = trees match { case left : : right : : cs => (make. Code. Tree(left, right) : : cs). sort. With((t 1, t 2) => weight(t 1) < weight(t 2)) case _ => trees } weight=1 Leaf(l, 1 ) weight=2 Fork(List(S, c), 2 ) Leaf(S, 1) Leaf(c, 1 ) weight=2 Leaf(a, 2 ) nil

create. Code. Tree (chars: List[Char]): Code. Tree def until(. . ). . { if

create. Code. Tree (chars: List[Char]): Code. Tree def until(. . ). . { if (p(trees)) trees else until(p, f)( f(trees) ) } def combine(trees: List[Code. Tree])… = trees match { case left : : right : : cs => (make. Code. Tree(left, right) : : cs). sort. With((t 1, t 2) => weight(t 1) < weight(t 2)) case _ => trees } Fork(List(l, S, c), 3 ) Leaf(l, 1 ) Fork(List(S, c), 2 ) Leaf(S, 1) Leaf(c, 1 ) Leaf(a, 2 ) nil

create. Code. Tree (chars: List[Char]): Code. Tree def until(. . ). . { if

create. Code. Tree (chars: List[Char]): Code. Tree def until(. . ). . { if (p(trees)) trees else until(p, f)( f(trees) ) } def combine(trees: List[Code. Tree])… = trees match { case left : : right : : cs => (make. Code. Tree(left, right) : : cs). sort. With((t 1, t 2) => weight(t 1) < weight(t 2)) case _ => trees } weight=3 Fork(List(l, S, c), 3 ) Leaf(l, 1 ) Fork(List(S, c), 2 ) Leaf(S, 1) Leaf(c, 1 ) weight=2 Leaf(a, 2 ) nil

create. Code. Tree (chars: List[Char]): Code. Tree def until(. . ). . { if

create. Code. Tree (chars: List[Char]): Code. Tree def until(. . ). . { if (p(trees)) trees else until(p, f)( f(trees) ) } def combine(trees: List[Code. Tree])… = trees match { case left : : right : : cs => (make. Code. Tree(left, right) : : cs). sort. With((t 1, t 2) => weight(t 1) < weight(t 2)) case _ => trees } weight=2 Leaf(a, 2 weight=3 ) Fork(List(l, S, c), 3 ) Leaf(l, 1 ) Fork(List(S, c), 2 ) Leaf(S, 1) Leaf(c, 1 ) nil

create. Code. Tree (chars: List[Char]): Code. Tree def until(. . ). . { if

create. Code. Tree (chars: List[Char]): Code. Tree def until(. . ). . { if (p(trees)) trees else until(p, f)( f(trees) ) } def combine(trees: List[Code. Tree])… = trees match { case left : : right : : cs => (make. Code. Tree(left, right) : : cs). sort. With((t 1, t 2) => weight(t 1) < weight(t 2)) case _ => trees } Fork(List(a, l, S, c), 5) Leaf(a, 2 ) nil Fork(List(l, S, c), 3 ) Leaf(l, 1 ) Fork(List(S, c), 2 ) Leaf(S, 1) Leaf(c, 1 )

encode(tree: Code. Tree)(text: List[Char]): List[Bit] type Bit = Int … def encode(tree: Code. Tree)(text:

encode(tree: Code. Tree)(text: List[Char]): List[Bit] type Bit = Int … def encode(tree: Code. Tree)(text: List[Char]): List[Bit] = { def lookup(tree: Code. Tree)(c: Char): List[Bit] = tree match { case Leaf(_, _) => List() case Fork(left, right, _, _) if chars(left). contains(c) => 0 : : lookup(left)(c) case Fork(left, right, _, _) => 1 : : lookup(right)(c) } text flat. Map lookup(tree) } flat. Map List(S, c, a, l, a) lookup

encode(tree: Code. Tree)(text: List[Char]): List[Bit] def encode(tree: Code. Tree)(text: List[Char]): List[Bit] = { def

encode(tree: Code. Tree)(text: List[Char]): List[Bit] def encode(tree: Code. Tree)(text: List[Char]): List[Bit] = { def lookup(tree: Code. Tree)(c: Char): List[Bit] = tree match { case Leaf(_, _) => List() case Fork(left, right, _, _) if chars(left). contains(c) => 0 : : lookup(left)(c) case Fork(left, right, _, _) => 1 : : lookup(right)(c) } text flat. Map lookup(tree) } S 1 List(1)

encode(tree: Code. Tree)(text: List[Char]): List[Bit] def encode(tree: Code. Tree)(text: List[Char]): List[Bit] = { def

encode(tree: Code. Tree)(text: List[Char]): List[Bit] def encode(tree: Code. Tree)(text: List[Char]): List[Bit] = { def lookup(tree: Code. Tree)(c: Char): List[Bit] = tree match { case Leaf(_, _) => List() case Fork(left, right, _, _) if chars(left). contains(c) => 0 : : lookup(left)(c) case Fork(left, right, _, _) => 1 : : lookup(right)(c) } text flat. Map lookup(tree) } S 1 1 List(1, 1)

encode(tree: Code. Tree)(text: List[Char]): List[Bit] def encode(tree: Code. Tree)(text: List[Char]): List[Bit] = { def

encode(tree: Code. Tree)(text: List[Char]): List[Bit] def encode(tree: Code. Tree)(text: List[Char]): List[Bit] = { def lookup(tree: Code. Tree)(c: Char): List[Bit] = tree match { case Leaf(_, _) => List() case Fork(left, right, _, _) if chars(left). contains(c) => 0 : : lookup(left)(c) case Fork(left, right, _, _) => 1 : : lookup(right)(c) } text flat. Map lookup(tree) } S 1 1 List(1, 1, 0) 0

encode(tree: Code. Tree)(text: List[Char]): List[Bit] def encode(tree: Code. Tree)(text: List[Char]): List[Bit] = { def

encode(tree: Code. Tree)(text: List[Char]): List[Bit] def encode(tree: Code. Tree)(text: List[Char]): List[Bit] = { def lookup(tree: Code. Tree)(c: Char): List[Bit] = tree match { case Leaf(_, _) => List() case Fork(left, right, _, _) if chars(left). contains(c) => 0 : : lookup(left)(c) case Fork(left, right, _, _) => 1 : : lookup(right)(c) } text flat. Map lookup(tree) } c 1 1 List(1, 1, 1) 1

encode(tree: Code. Tree)(text: List[Char]): List[Bit] def encode(tree: Code. Tree)(text: List[Char]): List[Bit] = { def

encode(tree: Code. Tree)(text: List[Char]): List[Bit] def encode(tree: Code. Tree)(text: List[Char]): List[Bit] = { def lookup(tree: Code. Tree)(c: Char): List[Bit] = tree match { case Leaf(_, _) => List() case Fork(left, right, _, _) if chars(left). contains(c) => 0 : : lookup(left)(c) case Fork(left, right, _, _) => 1 : : lookup(right)(c) } text flat. Map lookup(tree) } a 0 List(0)

encode(tree: Code. Tree)(text: List[Char]): List[Bit] def encode(tree: Code. Tree)(text: List[Char]): List[Bit] = { def

encode(tree: Code. Tree)(text: List[Char]): List[Bit] def encode(tree: Code. Tree)(text: List[Char]): List[Bit] = { def lookup(tree: Code. Tree)(c: Char): List[Bit] = tree match { case Leaf(_, _) => List() case Fork(left, right, _, _) if chars(left). contains(c) => 0 : : lookup(left)(c) case Fork(left, right, _, _) => 1 : : lookup(right)(c) } text flat. Map lookup(tree) } l 1 0 List(1, 0)

encode(tree: Code. Tree)(text: List[Char]): List[Bit] def encode(tree: Code. Tree)(text: List[Char]): List[Bit] = { def

encode(tree: Code. Tree)(text: List[Char]): List[Bit] def encode(tree: Code. Tree)(text: List[Char]): List[Bit] = { def lookup(tree: Code. Tree)(c: Char): List[Bit] = tree match { case Leaf(_, _) => List() case Fork(left, right, _, _) if chars(left). contains(c) => 0 : : lookup(left)(c) case Fork(left, right, _, _) => 1 : : lookup(right)(c) } text flat. Map lookup(tree) } a 0 List(0)

encode(tree: Code. Tree)(text: List[Char]): List[Bit] def encode(tree: Code. Tree)(text: List[Char]): List[Bit] = { def

encode(tree: Code. Tree)(text: List[Char]): List[Bit] def encode(tree: Code. Tree)(text: List[Char]): List[Bit] = { def lookup(tree: Code. Tree)(c: Char): List[Bit] = tree match { case Leaf(_, _) => List() case Fork(left, right, _, _) if chars(left). contains(c) => 0 : : lookup(left)(c) case Fork(left, right, _, _) => 1 : : lookup(right)(c) } text flat. Map lookup(tree) } List(S, c, a, l, a) flat. Map lookup List(1, 1, 0), List(1, 1, 1), List(0), List(1, 0), List(0)) List(1, 1, 0, 0)

decode(tree: Code. Tree, bits: List[Bit]): List[Char] def decode(tree: Code. Tree, bits: List[Bit]): List[Char] =

decode(tree: Code. Tree, bits: List[Bit]): List[Char] def decode(tree: Code. Tree, bits: List[Bit]): List[Char] = { def traverse(remaining: Code. Tree, bits: List[Bit]): List[Char] = remaining match { case Leaf(c, _) if bits. is. Empty => List(c) case Leaf(c, _) => c : : traverse(tree, bits) case Fork(left, right, _, _) if bits. head == 0 => traverse(left, bits. tail) case Fork(left, right, _, _) => traverse(right, bits. tail) } traverse(tree, bits) } List(1, 1, 0, 0) traverse List(S, c, a, l, a)

decode(tree: Code. Tree, bits: List[Bit]): List[Char] def decode(tree: Code. Tree, bits: List[Bit]): List[Char] =

decode(tree: Code. Tree, bits: List[Bit]): List[Char] def decode(tree: Code. Tree, bits: List[Bit]): List[Char] = { def traverse(remaining: Code. Tree, bits: List[Bit]): List[Char] = remaining match { case Leaf(c, _) if bits. is. Empty => List(c) case Leaf(c, _) => c : : traverse(tree, bits) case Fork(left, right, _, _) if bits. head == 0 => traverse(left, bits. tail) case Fork(left, right, _, _) => traverse(right, bits. tail) } traverse(tree, bits) } List(1, 1, 0, 0)

decode(tree: Code. Tree, bits: List[Bit]): List[Char] def decode(tree: Code. Tree, bits: List[Bit]): List[Char] =

decode(tree: Code. Tree, bits: List[Bit]): List[Char] def decode(tree: Code. Tree, bits: List[Bit]): List[Char] = { def traverse(remaining: Code. Tree, bits: List[Bit]): List[Char] = remaining match { case Leaf(c, _) if bits. is. Empty => List(c) case Leaf(c, _) => c : : traverse(tree, bits) case Fork(left, right, _, _) if bits. head == 0 => traverse(left, bits. tail) case Fork(left, right, _, _) => traverse(right, bits. tail) } traverse(tree, bits) } List(1, 1, 0, 0)

decode(tree: Code. Tree, bits: List[Bit]): List[Char] def decode(tree: Code. Tree, bits: List[Bit]): List[Char] =

decode(tree: Code. Tree, bits: List[Bit]): List[Char] def decode(tree: Code. Tree, bits: List[Bit]): List[Char] = { def traverse(remaining: Code. Tree, bits: List[Bit]): List[Char] = remaining match { case Leaf(c, _) if bits. is. Empty => List(c) case Leaf(c, _) => c : : traverse(tree, bits) case Fork(left, right, _, _) if bits. head == 0 => traverse(left, bits. tail) case Fork(left, right, _, _) => traverse(right, bits. tail) } traverse(tree, bits) } List(1, 1, 0, 0)

decode(tree: Code. Tree, bits: List[Bit]): List[Char] def decode(tree: Code. Tree, bits: List[Bit]): List[Char] =

decode(tree: Code. Tree, bits: List[Bit]): List[Char] def decode(tree: Code. Tree, bits: List[Bit]): List[Char] = { def traverse(remaining: Code. Tree, bits: List[Bit]): List[Char] = remaining match { case Leaf(c, _) if bits. is. Empty => List(c) case Leaf(c, _) => c : : traverse(tree, bits) case Fork(left, right, _, _) if bits. head == 0 => traverse(left, bits. tail) case Fork(left, right, _, _) => traverse(right, bits. tail) } traverse(tree, bits) } List(1, 1, 0, 0) List(S)

decode(tree: Code. Tree, bits: List[Bit]): List[Char] def decode(tree: Code. Tree, bits: List[Bit]): List[Char] =

decode(tree: Code. Tree, bits: List[Bit]): List[Char] def decode(tree: Code. Tree, bits: List[Bit]): List[Char] = { def traverse(remaining: Code. Tree, bits: List[Bit]): List[Char] = remaining match { case Leaf(c, _) if bits. is. Empty => List(c) case Leaf(c, _) => c : : traverse(tree, bits) case Fork(left, right, _, _) if bits. head == 0 => traverse(left, bits. tail) case Fork(left, right, _, _) => traverse(right, bits. tail) } traverse(tree, bits) } List(1, 1, 0, 0) List(S, c, a, l, a)

quick. Encode(tree: Code. Tree)(text: List[Char]): List[Bit] type Code = (Char, List[Bit]) type Code. Table

quick. Encode(tree: Code. Tree)(text: List[Char]): List[Bit] type Code = (Char, List[Bit]) type Code. Table = List[(Char, List[Bit])] def quick. Encode(tree: Code. Tree)(text: List[Char]): List[Bit] = text flat. Map code. Bits(convert(tree)) Code. Table convert List( (a, List(0)), (l, List(1, 0)), (S, List(1, 1, 0)), (c, List(1, 1, 1)) ) flat. Map List(S, c, a, l, a) code. Bits List(1, 1, 0, 0)

convert(tree: Code. Tree): Code. Table def convert(tree: Code. Tree): Code. Table = tree match

convert(tree: Code. Tree): Code. Table def convert(tree: Code. Tree): Code. Table = tree match { case Leaf(c, w) => List( (c, List()) ) case Fork(left, right, cs, w) => merge. Code. Tables(convert(left), convert(right)) } merge. Code. Tables List(a, List()) List(l, List()) List(S, List()) merge. Code. Tables List(c, List())

convert(tree: Code. Tree): Code. Table def convert(tree: Code. Tree): Code. Table = tree match

convert(tree: Code. Tree): Code. Table def convert(tree: Code. Tree): Code. Table = tree match { case Leaf(c, w) => List( (c, List()) ) case Fork(left, right, cs, w) => merge. Code. Tables(convert(left), convert(right)) } def merge. Code. Tables(a: Code. Table, b: Code. Table): Code. Table = { def prepend(b: Bit)(code: Code): Code = (code. _1, b : : code. _2) a. map(prepend(0)) : : : b. map(prepend(1)) } List((a, List(0)), (l, List(1, 0)), (S, List(1, 1, 0)), (c, List(1, 1, 1))) List((l, List(0)), (S, List(1, 0)), (c, List(1, 1))) List(a, List()) List(l, List()) List(S, List()) List((S, List(0)), (c, List(1)) ) List(c, List())

quick. Encode(tree: Code. Tree)(text: List[Char]): List[Bit] def quick. Encode(tree: Code. Tree)(text: List[Char]): List[Bit] =

quick. Encode(tree: Code. Tree)(text: List[Char]): List[Bit] def quick. Encode(tree: Code. Tree)(text: List[Char]): List[Bit] = text flat. Map code. Bits(convert(tree)) def code. Bits(table: Code. Table)(char: Char): List[Bit] = { table. filter( (code) => code. _1 == char ). head. _2 } Code. Table (a, List(0)) (l, List(1, 0)) (S, List(1, 1, 0)) (c, List(1, 1, 1)) ) S List(1, 1, 0) c List(1, 1, 1) a List(0) l List(1, 0) a List(0) List(1, 1, 0, 0 )