Download presentation
Presentation is loading. Please wait.
1
Assignment 4 Kang-Pil Kim, Jin Kim
Huffman code Assignment 4 Kang-Pil Kim, Jin Kim
2
Huffman Code 허프만 부호화의 기본 개념은 각 단위 정보를 표현하는 비트 수 를 단위 정보들의 출현 빈도를 기반으로 할당 빈도가 높은 정보는 적은 비트 수를 사용하여 표현하고, 빈도가 적은 정보는 비트 수를 많이 사용하여 전체 필요한 비트 양을 줄임
3
Ex) Huffman List(“s,” “c”, “a”, “l”, “a”)
List((s, 1), (c, 1), (l, 1), (a, 2) // 빈도수로 정렬
4
Ex) Huffman List((s, 1), (c, 1), (l, 1), (a, 2) (a, l, s, c), 5 1 a, 2
1 a, 2 (l, s, c), 3 10 11 l, 1 (s, c), 2 110 111 s, 1 c, 1
5
Code abstract class CodeTree case class Fork( left: CodeTree,
right: CodeTree, chars: List[Char], weight: Int) extends CodeTree case class Leaf(char: Char, weight: Int) extends CodeTree
6
Code def weight(tree: CodeTree): Int = tree match {
case Fork(_,_,_,w) => w case Leaf(_,w) => w } def chars(tree: CodeTree): List[Char] = tree match { case Fork(_,_,cs,_) => cs case Leaf(c,_) => List(c)
7
Code def makeCodeTree(left: CodeTree, right: CodeTree) =
Fork( left, right, chars(left) ::: chars(right), weight(left) + weight(right)) (s, a), 2 s, 1 a, 1 s, 1 a, 1
8
Code def string2Chars(str: String): List[Char] = str.toList
def singleton(trees: List[CodeTree]): Boolean = trees.size == 1
9
List(“s”, ”c”, ”a”, ”l”, ”a”)
Code def times(chars: List[Char]): List[(Char, Int)] = { // 빈도수 체크 후 Weight value생성 def incr(acc:Map[Char, Int], c:Char) = { val count = (acc get c).getOrElse(0) + 1 acc + ((c, count)) } (Map[Char,Int]() /: chars)(incr).iterator.toList /: => foldleft Map((s,1), (c,1)) Map((s,1)) ‘c’ List(“s”, ”c”, ”a”, ”l”, ”a”) Map() ‘s’
10
FoldLeft (xs foldLeft Accumulate) (function) ‘0’ for ‘+’ operator
11
Code def makeOrderedLeafList(freqs: List[(Char, Int)]): List[Leaf] = {
freqs.sortWith((f1, f2) => f1._2 < f2._2) // 오름차순 정렬 .map((f) => Leaf (f._1, f._2)) //각 리스트들의 원소들을 Leaf로 생성 }
12
Code def combine(trees: List[CodeTree]): List[CodeTree] = trees match { case left :: right :: cs => (makeCodeTree(left,right) ::cs) .sortWith((t1, t2) => weight(t1) < weight(t2)) case _ => trees } s, a, 2 s, 1 a, 1 l, 1 s, 1 a, 1 l, 1 Nil
13
Code def until(p: List[CodeTree]=>Boolean, // singleton
f: List[CodeTree]=>List[CodeTree]) //combine (trees: List[CodeTree]) : List[CodeTree] = { if (p(trees)) trees // if singleton is true else until(p, f)( f(trees) ) // else recursive until() }
14
PATMAT “Scala” List(1, 1, 0, 1, 1, 1, 0, 1, 0, 0) List(S, c, a, l, a)
string2Chars createCodeTree quickEncode convert encode codeBits List(1, 1, 0, 1, 1, 1, 0, 1, 0, 0) decode List(S, c, a, l, a)
15
createCodeTree (chars: List[Char]): CodeTree
def createCodeTree(chars: List[Char]): CodeTree = { until(singleton, combine)( makeOrderedLeafList(times(chars)) ).head } List(S, c, a, l, a) times List((S,1), (c,1), (a,2), (l,1)) makeOrderedLeafList 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) )
16
createCodeTree (chars: List[Char]): CodeTree
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)
17
createCodeTree (chars: List[Char]): CodeTree
Leaf(S,1) Leaf(c,1) Leaf(l,1) Leaf(a,2) nil
18
createCodeTree (chars: List[Char]): CodeTree
def until(..)..{ if (p(trees)) trees else until(p, f)( f(trees) ) } def combine(trees: List[CodeTree])… = trees match { case left :: right :: cs => (makeCodeTree(left, right) :: cs) .sortWith((t1, t2) => weight(t1) < weight(t2)) case _ => trees } Fork(List(S,c),2) Leaf(l,1) Leaf(S,1) Leaf(c,1) Leaf(a,2) nil
19
createCodeTree (chars: List[Char]): CodeTree
def until(..)..{ if (p(trees)) trees else until(p, f)( f(trees) ) } def combine(trees: List[CodeTree])… = trees match { case left :: right :: cs => (makeCodeTree(left, right) :: cs) .sortWith((t1, t2) => weight(t1) < weight(t2)) case _ => trees } weight=2 weight=1 Fork(List(S,c),2) Leaf(l,1) Leaf(S,1) Leaf(c,1) weight=2 Leaf(a,2) nil
20
createCodeTree (chars: List[Char]): CodeTree
def until(..)..{ if (p(trees)) trees else until(p, f)( f(trees) ) } def combine(trees: List[CodeTree])… = trees match { case left :: right :: cs => (makeCodeTree(left, right) :: cs) .sortWith((t1, t2) => weight(t1) < weight(t2)) case _ => trees } weight=1 Leaf(l,1) weight=2 Fork(List(S,c),2) weight=2 Leaf(S,1) Leaf(c,1) Leaf(a,2) nil
21
createCodeTree (chars: List[Char]): CodeTree
def until(..)..{ if (p(trees)) trees else until(p, f)( f(trees) ) } def combine(trees: List[CodeTree])… = trees match { case left :: right :: cs => (makeCodeTree(left, right) :: cs) .sortWith((t1, t2) => weight(t1) < weight(t2)) case _ => trees } Fork(List(l,S,c),3) Leaf(l,1) Fork(List(S,c),2) Leaf(a,2) nil Leaf(S,1) Leaf(c,1)
22
createCodeTree (chars: List[Char]): CodeTree
def until(..)..{ if (p(trees)) trees else until(p, f)( f(trees) ) } def combine(trees: List[CodeTree])… = trees match { case left :: right :: cs => (makeCodeTree(left, right) :: cs) .sortWith((t1, t2) => weight(t1) < weight(t2)) case _ => trees } weight=3 Fork(List(l,S,c),3) weight=2 Leaf(l,1) Fork(List(S,c),2) Leaf(a,2) nil Leaf(S,1) Leaf(c,1)
23
createCodeTree (chars: List[Char]): CodeTree
def until(..)..{ if (p(trees)) trees else until(p, f)( f(trees) ) } def combine(trees: List[CodeTree])… = trees match { case left :: right :: cs => (makeCodeTree(left, right) :: cs) .sortWith((t1, t2) => weight(t1) < weight(t2)) case _ => trees } weight=2 Leaf(a,2) weight=3 Fork(List(l,S,c),3) nil Leaf(l,1) Fork(List(S,c),2) Leaf(S,1) Leaf(c,1)
24
createCodeTree (chars: List[Char]): CodeTree
def until(..)..{ if (p(trees)) trees else until(p, f)( f(trees) ) } def combine(trees: List[CodeTree])… = trees match { case left :: right :: cs => (makeCodeTree(left, right) :: cs) .sortWith((t1, t2) => weight(t1) < weight(t2)) case _ => trees } Fork(List(a,l,S,c),5) nil Leaf(a,2) Fork(List(l,S,c),3) Leaf(l,1) Fork(List(S,c),2) Leaf(S,1) Leaf(c,1)
25
encode(tree: CodeTree)(text: List[Char]): List[Bit]
type Bit = Int … def encode(tree: CodeTree)(text: List[Char]): List[Bit] = { def lookup(tree: CodeTree)(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 flatMap lookup(tree) List(S, c, a, l, a) flatMap lookup
26
encode(tree: CodeTree)(text: List[Char]): List[Bit]
def encode(tree: CodeTree)(text: List[Char]): List[Bit] = { def lookup(tree: CodeTree)(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 flatMap lookup(tree) S 1 List(1)
27
encode(tree: CodeTree)(text: List[Char]): List[Bit]
def encode(tree: CodeTree)(text: List[Char]): List[Bit] = { def lookup(tree: CodeTree)(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 flatMap lookup(tree) S 1 1 List(1,1)
28
encode(tree: CodeTree)(text: List[Char]): List[Bit]
def encode(tree: CodeTree)(text: List[Char]): List[Bit] = { def lookup(tree: CodeTree)(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 flatMap lookup(tree) S 1 1 List(1,1,0)
29
encode(tree: CodeTree)(text: List[Char]): List[Bit]
def encode(tree: CodeTree)(text: List[Char]): List[Bit] = { def lookup(tree: CodeTree)(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 flatMap lookup(tree) c 1 1 1 List(1,1,1)
30
encode(tree: CodeTree)(text: List[Char]): List[Bit]
def encode(tree: CodeTree)(text: List[Char]): List[Bit] = { def lookup(tree: CodeTree)(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 flatMap lookup(tree) a List(0)
31
encode(tree: CodeTree)(text: List[Char]): List[Bit]
def encode(tree: CodeTree)(text: List[Char]): List[Bit] = { def lookup(tree: CodeTree)(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 flatMap lookup(tree) l 1 List(1,0)
32
encode(tree: CodeTree)(text: List[Char]): List[Bit]
def encode(tree: CodeTree)(text: List[Char]): List[Bit] = { def lookup(tree: CodeTree)(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 flatMap lookup(tree) a List(0)
33
encode(tree: CodeTree)(text: List[Char]): List[Bit]
def encode(tree: CodeTree)(text: List[Char]): List[Bit] = { def lookup(tree: CodeTree)(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 flatMap lookup(tree) List(S, c, a, l, a) flatMap List(List(1,1,0), List(1,1,1), List(0), List(1,0), List(0)) lookup List(1,1,0,1,1,1,0,1,0,0)
34
decode(tree: CodeTree, bits: List[Bit]): List[Char]
def decode(tree: CodeTree, bits: List[Bit]): List[Char] = { def traverse(remaining: CodeTree, bits: List[Bit]): List[Char] = remaining match { case Leaf(c, _) if bits.isEmpty => 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,1,1,1,0,1,0,0) traverse List(S, c, a, l, a)
35
decode(tree: CodeTree, bits: List[Bit]): List[Char]
def decode(tree: CodeTree, bits: List[Bit]): List[Char] = { def traverse(remaining: CodeTree, bits: List[Bit]): List[Char] = remaining match { case Leaf(c, _) if bits.isEmpty => 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,1,1,1,0,1,0,0)
36
decode(tree: CodeTree, bits: List[Bit]): List[Char]
def decode(tree: CodeTree, bits: List[Bit]): List[Char] = { def traverse(remaining: CodeTree, bits: List[Bit]): List[Char] = remaining match { case Leaf(c, _) if bits.isEmpty => 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,1,1,1,0,1,0,0)
37
decode(tree: CodeTree, bits: List[Bit]): List[Char]
def decode(tree: CodeTree, bits: List[Bit]): List[Char] = { def traverse(remaining: CodeTree, bits: List[Bit]): List[Char] = remaining match { case Leaf(c, _) if bits.isEmpty => 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,1,1,1,0,1,0,0)
38
decode(tree: CodeTree, bits: List[Bit]): List[Char]
def decode(tree: CodeTree, bits: List[Bit]): List[Char] = { def traverse(remaining: CodeTree, bits: List[Bit]): List[Char] = remaining match { case Leaf(c, _) if bits.isEmpty => 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,1,1,1,0,1,0,0) List(S)
39
decode(tree: CodeTree, bits: List[Bit]): List[Char]
def decode(tree: CodeTree, bits: List[Bit]): List[Char] = { def traverse(remaining: CodeTree, bits: List[Bit]): List[Char] = remaining match { case Leaf(c, _) if bits.isEmpty => 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,1,1,1,0,1,0,0) List(S, c, a, l, a)
40
quickEncode(tree: CodeTree)(text: List[Char]): List[Bit]
type Code = (Char, List[Bit]) type CodeTable = List[(Char, List[Bit])] def quickEncode(tree: CodeTree)(text: List[Char]): List[Bit] = text flatMap codeBits(convert(tree)) CodeTable List( (a,List(0)), (l,List(1, 0)), (S,List(1, 1, 0)), (c,List(1, 1, 1)) ) convert flatMap codeBits List(S, c, a, l, a) List(1,1,0,1,1,1,0,1,0,0)
41
convert(tree: CodeTree): CodeTable
def convert(tree: CodeTree): CodeTable = tree match { case Leaf(c, w) => List( (c, List()) ) case Fork(left, right, cs, w) => mergeCodeTables(convert(left), convert(right)) } mergeCodeTables mergeCodeTables List(a,List()) mergeCodeTables List(l,List()) List(S,List()) List(c,List())
42
convert(tree: CodeTree): CodeTable
def convert(tree: CodeTree): CodeTable = tree match { case Leaf(c, w) => List( (c, List()) ) case Fork(left, right, cs, w) => mergeCodeTables(convert(left), convert(right)) } def mergeCodeTables(a: CodeTable, b: CodeTable): CodeTable = { 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((S,List(0)),(c,List(1))) List(l,List()) List(S,List()) List(c,List())
43
quickEncode(tree: CodeTree)(text: List[Char]): List[Bit]
def quickEncode(tree: CodeTree)(text: List[Char]): List[Bit] = text flatMap codeBits(convert(tree)) def codeBits(table: CodeTable)(char: Char): List[Bit] = { table.filter( (code) => code._1 == char ).head._2 } CodeTable S c a l List(1, 1, 0) (a,List(0)) (l,List(1, 0)) (S,List(1, 1, 0)) (c,List(1, 1, 1)) ) List(1, 1, 1) List(1,1,0,1,1,1,0,1,0,0) List(0) List(1,0) List(0)
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.