Advertisement
Guest User

Untitled

a guest
Jan 31st, 2015
164
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.80 KB | None | 0 0
  1. package main
  2.  
  3. import (
  4. "container/heap"
  5. "container/list"
  6. "fmt"
  7. "log"
  8. )
  9.  
  10. type charFreq struct {
  11. letter uint8
  12. count int
  13. }
  14.  
  15. type huffmanNode struct {
  16. letter uint8
  17. freq float32
  18. left *huffmanNode
  19. right *huffmanNode
  20. }
  21.  
  22. func encodeString(inputString string, rootNode *huffmanNode) string {
  23. if len(inputString) == 0 {
  24. log.Fatal("Empty inputString")
  25. }
  26. if rootNode == nil {
  27. log.Fatal("Nil rootNode")
  28. }
  29.  
  30. encodingCache := make(map[uint8]string)
  31. var outputString string
  32. for _, c := range inputString {
  33. encodedChar, isPresent := encodingCache[uint8(c)]
  34. if !isPresent {
  35. encodedChar = getEncodingForChar(uint8(c), rootNode, "")
  36. encodingCache[uint8(c)] = encodedChar
  37. }
  38. outputString = outputString + encodedChar
  39. }
  40.  
  41. return outputString
  42. }
  43.  
  44. func getEncodingForChar(letter uint8, huffmanTree *huffmanNode, output string) string {
  45. if letter == huffmanTree.letter {
  46. return output
  47. } else {
  48. var result string
  49. if huffmanTree.left != nil {
  50. result = getEncodingForChar(letter, huffmanTree.left, output+"0")
  51. }
  52. if huffmanTree.right != nil && result == "" {
  53. result = getEncodingForChar(letter, huffmanTree.right, output+"1")
  54. }
  55. return result
  56. }
  57. }
  58.  
  59. func buildHuffmanTree(inputStrLength int, charFreqList *list.List) *huffmanNode {
  60. pq := make(PriorityQueue, charFreqList.Len())
  61.  
  62. for i, e := 0, charFreqList.Front(); e != nil; i, e = i+1, e.Next() {
  63. charFreq1 := e.Value.(charFreq)
  64. pq[i] = &Item{
  65. priority: float32(charFreq1.count) / float32(inputStrLength),
  66. value: &huffmanNode{
  67. letter: charFreq1.letter,
  68. freq: float32(charFreq1.count) / float32(inputStrLength),
  69. },
  70. }
  71. }
  72. heap.Init(&pq) //insert entire array into heap
  73.  
  74. for pq.Len() > 1 {
  75. x := heap.Pop(&pq).(*Item)
  76. y := heap.Pop(&pq).(*Item)
  77. z := Item{
  78. priority: x.priority + y.priority,
  79. value: &huffmanNode{
  80. freq: x.priority + y.priority,
  81. left: x.value,
  82. right: y.value,
  83. },
  84. }
  85. heap.Push(&pq, &z)
  86. }
  87.  
  88. return heap.Pop(&pq).(*Item).value
  89. }
  90.  
  91. func determineCharFreq(inputStr string) *list.List {
  92. charFreqList := list.New()
  93. for i := 0; i < len(inputStr); i++ {
  94. for e := charFreqList.Front(); true; e = e.Next() {
  95. if e == nil {
  96. charFreqList.PushBack(charFreq{letter: inputStr[i], count: 1})
  97. break
  98. }
  99. charFreq1 := e.Value.(charFreq) //this makes a copy(!)
  100. if charFreq1.letter == inputStr[i] {
  101. e.Value = charFreq{letter: inputStr[i], count: charFreq1.count + 1}
  102. break
  103. }
  104. }
  105. }
  106.  
  107. for e := charFreqList.Front(); e != nil; e = e.Next() {
  108. charFreq1 := e.Value.(charFreq)
  109. fmt.Printf("%c=%v\n", charFreq1.letter, charFreq1.count)
  110. }
  111.  
  112. return charFreqList
  113. }
  114.  
  115. func main() {
  116. inputStr := "TAATTAGAAATTCTATTATA"
  117. fmt.Println(inputStr)
  118. charFreqList := determineCharFreq(inputStr)
  119. rootNode := buildHuffmanTree(len(inputStr), charFreqList)
  120. fmt.Println("output:", encodeString(inputStr, rootNode))
  121. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement