国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發(fā) > 綜合 > 正文

一個小巧但好用的數(shù)據(jù)庫壓縮算法

2024-07-21 02:37:49
字體:
來源:轉載
供稿:網(wǎng)友

  常用的壓縮工具(如 WinZip 或 ARJ)現(xiàn)在也不起作用,因為我們并不是對整個數(shù)據(jù)庫進行壓縮(那樣光盤上的數(shù)據(jù)將無法檢索),而只是要將數(shù)據(jù)庫中的某些字段的內(nèi)容壓縮后存入庫中——以減少整個數(shù)據(jù)庫占用的空間——然后在使用中動態(tài)解壓將數(shù)據(jù)還原為本來面目。
  
  最理想的辦法當然是數(shù)據(jù)庫系統(tǒng)(DBMS)本身直接支持數(shù)據(jù)壓縮存儲,但令人遺憾的是:常見的DBMS均未提供該功能。
  
  在互聯(lián)網(wǎng)上確實能找到一些有關數(shù)據(jù)壓縮的思想、算法甚至 C語言的部分源代碼,但它們大都過于復雜,或應用范圍有限(如僅對圖像或純數(shù)字數(shù)據(jù)有效),或是在版權方面有太苛刻的要求。
  
  最后我們采用了自行設計的算法。該方法的壓縮率只有 20%至25% ,但它小巧、輕易實現(xiàn),在實際應用中取得了良好的效果。
  
  一、算法概述
  壓縮冗余的比特位(bit)是常見的壓縮思想之一。
  例如,字符串 CCW-2000 的二進制表示為:
  01000011,01000011,01010111,00101101,00110010,00110000,00110000,00110000
  其中每個二進制的前導“0”是冗余的,去掉前導“0”后的表示為:
  1000011,1000011,1010111,101101,110010,110000,110000,110000
  
  這顯然達到了數(shù)據(jù)壓縮的目的,但同時也帶來一個很大的問題:二進制流僅僅由“0”和“1”組成,并不存在上面為了表述清楚而加入的“,”。 即:由于壓縮后的二進制不再是“定長”的,兩個二進制之間如何“劃界”成了難題。
  
  常見的解決方案有:霍夫曼表(Huffman codes)、LZW的動態(tài)查詢表、Markov的多維長度字典表,以及根據(jù)前值和前長度變換應用規(guī)則的DAKX方法等。但這些方法大都過于繁雜或未公布技術細節(jié)而難以實現(xiàn)。
  
  為了實現(xiàn)起來簡捷,避免用“宰牛刀”,我們設計的算法采用一種折衷的思想:用“縮短”了的“定長”二進制來實現(xiàn)壓縮,同時又避免了“劃界”的難題。
  
  具體思路是:
  (1) 所有字符的二進制長度均為 6個 bit而不是一般的 8個 bit。即每個字符節(jié)約 2個 bit。這決定了本方法的理想(最高)壓縮率為 25%。
  (2) 由于 6個 bit僅能區(qū)分64種字符,故將內(nèi)碼小于 127的字符分為“常用”和“不常用”兩組。
  (3) 第一組由英文字母(大小寫)、0至9的數(shù)字、空格以及一個控制字符
  
  組成;第二組由內(nèi)碼小于 127的其它字符組成。
  
  (4) 每組內(nèi)的字符均重新編碼,以使其“新內(nèi)碼”均小于64。
  (5) 第二組的每個字符前均以第一組中的控制字符做前綴。
  (6) 內(nèi)碼大于等于 127的字符用普通的 8-bit表示,前綴是兩個連續(xù)的第一組中的控制字符。
  (7) 本方法顯然僅適用于西文文本。
  (8) 壓縮后的數(shù)據(jù)相當于被加密了,這大大提高了信息安全性。
  
  二、算法實現(xiàn)
  我們制作的西歐進出口商數(shù)據(jù)庫中有大量大段的企業(yè)英文描述,故應用上述算法非常成功,如愿以償?shù)貙⒄麄€系統(tǒng)的大小降到了 600兆以下,可以輕松地裝入一張光盤中。
  
  檢索系統(tǒng)用VB編程,數(shù)據(jù)庫用的是 MS-access。
  
  后附程序為清楚起見,將壓縮數(shù)據(jù)庫的功能改為壓縮文本文件的功能。該程序已在機器上測試通過,可作為一個壓縮工具單獨運行(為了同時說明壓縮及解壓縮這兩個函數(shù)的使用,下面的程序會將剛被壓縮的文件再進行解壓縮,解壓后文件與源文件是完全一樣的)。
  
  附完整的VB源代碼:
  Option EXPlicit
  Dim comped$, comping As String * 1, comping_p%, bit_p&
  Dim ebitmask(1 To 8) As Integer ' 存儲掩碼的數(shù)組
  Sub Command1_Click ()
  Dim ibuf$, obuf1$, obuf2$
  MousePointer = 11
  ' 設置掩碼
  ebitmask(1) = 128: ebitmask(2) = 64: ebitmask(3) = 32: ebitmask(4) = 16
  ebitmask(5) = 8: ebitmask(6) = 4: ebitmask(7) = 2: ebitmask(8) = 1
  Open "d:/temp/comPRess/theory.txt" For Input As #1 ' 壓縮前的源文件
  Open "d:/temp/compress/theory.6BT" For Output As #2 ' 壓縮后的文件
  Open "d:/temp/compress/theory_2.txt" For Output As #3 ' 解壓后的文件
  Do While Not EOF(1)
  Line Input #1, ibuf
  obuf1 = DoCompress(ibuf)
  Print #2, obuf1
  obuf2 = UnDoCompress(obuf1)
  Print #3, obuf2
  Loop
  Close #1, #2, #3
  MousePointer = 0
  End Sub
  Function DoCompress (in_buf$) As String ' 對輸入的字符串進行壓縮
  Dim i&, buf_len&, c As String * 1
  comped = "": comping = Chr(0): comping_p = 0
  buf_len = Len(in_buf)
  If buf_len > 0 Then
  For i = 1 To buf_len
  c = Mid(in_buf, i, 1)
  Select Case c
  Case " ", "A" To "Z", "a" To "z"
  putbits 0, c ' 第一組中的字符
  Case "!
" To "/", ":" To "@", "[" To "`", "{" To "~", Chr(1) To Chr(31)
  putbits 1, c ' 第二組中的字符
  Case Else
  putbits 2, c ' 其它字符
  End Select
  Next i
  putbits 3, Chr(0)
  End If
  DoCompress = comped
  End Function
  Sub putbits (flag%, cc$) ' 壓縮冗余的比特位(bits)
  Dim i%, c As String * 1
  c = cc
  Select Case flag
  Case 0 '對第一組中的字符內(nèi)碼進行重新定位
  Select Case c
  Case " "
  c = Chr(1)
  Case "0" To "9"
  c = Chr(Asc(c) - 46)
  Case "A" To "Z"
  c = Chr(Asc(c) - 53)
  Case "a" To "z"
  c = Chr(Asc(c) - 59)
  End Select
  Case 1 '對第二組中的字符內(nèi)碼進行重新定位
  Select Case c
  Case "!" To "/"
  c = Chr(Asc(c) - 32)
  Case ":" To "@"
  c = Chr(Asc(c) - 42)
  Case "[" To "`"
  c = Chr(Asc(c) - 68)
  Case "{" To "~"
  c = Chr(Asc(c) - 94)
  Case Chr(1) To Chr(31)
  c = Chr(Asc(c) + 32)
  End Select
  For i = 1 To 6
  putbit 0
  Next i
  Case 2
  For i = 1 To 12
  putbit 0
  Next i
  For i = 1 To 8
  If (Asc(c) And ebitmask(i)) <> 0 Then
  putbit 1
  Else
  putbit 0
  End If
  Next i
  Case 3
  For i = comping_p + 1 To 9
  putbit 0
  Next i
  End Select
  If flag < 2 Then
  For i = 1 To 6
  If (Asc(c) And ebitmask(i + 2)) <> 0 Then
  putbit 1
  Else
  putbit 0
  End If
  Next i
  End If
  End Sub
  Sub putbit (bit%) ' 設置比特位(bit)
  comping_p = comping_p + 1
  If comping_p > 8 Then
  comped = comped + comping
  comping = Chr(0)
  comping_p = 1
  End If
  If bit = 1 Then
  comping = Chr(Asc(comping) Or ebitmask(comping_p))
  End If
  End Sub
  Function UnDoCompress (in_buf$) As String ' 對輸入的字符串進行解壓縮
  Dim bits_buf%, out_buf$, c As String * 1, comped_len&
  comped = in_buf: bit_p = 1: comped_len = Len(comped) * 8
  Do While bit_p <= comped_len
  If comped_len - bit_p < 5 Then
  Exit Do
  End If
  bits_buf = getbits(6)
  If bits_buf <> 0 Then ' 根據(jù)控制字符判定字符的組別
  Select Case bits_buf
  Case 1
  c = " "
  Case 2 To 11 ' "0" To "9"
  c = Chr(bits_buf + 46)
  Case 12 To 37 ' "A" To "Z"
  c = Chr(bits_buf + 53)
  Case 38 To 63 ' "a" To "z"
  c = Chr(bits_buf + 59)
  End Select
  out_buf = out_buf + c
  Else
  If bit_p > comped_len Then
  Exit Do
  End If
  bits_buf = getbits(6)
  If bits_buf <> 0 Then
  Select Case bits_buf
  Case 1 To 15 ' "!" To "/"
  c = Chr(bits_buf + 32)
  Case 16 To 22 ' ":" To "@"
  c = Chr(bits_buf + 42)
  Case 23 To 28 ' "[" To "`"
  c = Chr(bits_buf + 68)
  Case 29 To 32 ' "{" To "~"
  c = Chr(bits_buf + 94)
  Case 33 To 63 ' Chr(1) To Chr(31)
  c = Chr(bits_buf - 32)
  End Select
  out_buf = out_buf + c
  Else
  bits_buf = getbits(8)
  out_buf = out_buf + Chr(bits_buf)
  End If
  End If
  Loop
  UnDoCompress = out_buf
  End Function
  Function getbits (numb As Integer) As Integer ' 獲取比特位(bit)
  Dim byte_p&, bit_o%, byte1 As String * 1, i%, j%, k%, m%
  byte_p = (bit_p / 8) + 1: bit_o = bit_p Mod 8
  byte1 = Mid(comped, byte_p, 1): j = 0: k = 0
  For i = bit_o To 8
  k = k + 1
  If k > numb Then
  Exit For
  End If
  If (Asc(byte1) And ebitmask(i)) <
> 0 Then
  j = j Or e

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 灌云县| 化德县| 漯河市| 扬州市| 本溪市| 长海县| 开阳县| 莒南县| 万荣县| 新密市| 定边县| 金山区| 毕节市| 台中县| 台北市| 宁海县| 广德县| 福海县| 福贡县| 金堂县| 嫩江县| 比如县| 通河县| 永胜县| 明光市| 南江县| 中卫市| 鸡西市| 朝阳市| 延吉市| 措美县| 鲁山县| 台中县| 贞丰县| 南京市| 张家界市| 久治县| 通城县| 宜兰市| 普洱| 吉木萨尔县|