2017-04-17 5 views
2

を作成しながら、「/ N」、「/ T」と同様のアスキーキーを処理する方法を、私はハフマンアルゴリズムを使用してファイルを圧縮する必要があります。私は、ファイルを処理しながら、私がこれまで行ってきたものですが、しかし、私は他の文字を取得することはできないのですが、私は苦労していますように、改行、タブ、etc.Thisなど、他のASCII文字を扱う、部品のほとんどを考え出しました創造。は私のプロジェクトのためにハフマン符号

import operator 

def getFreq(mylst): 
    dct = {'a':0,'b':0,'c':0,'d':0,'e':0,'f':0,'g':0,'h':0,'i':0,'j':0,'k':0,'l':0, 
     'm':0,'n':0,'o':0,'p':0,'q':0,'r':0,'s':0,'t':0,'u':0,'v':0,'w':0,'x':0,'y':0,'z':0,' ':0, 
     'A':0,'B':0,'C':0,'D':0,'E':0,'F':0,'G':0,'H':0,'I':0,'J':0,'K':0,'L':0, 
     'M':0,'N':0,'O':0,'P':0,'Q':0,'R':0,'S':0,'T':0,'U':0,'V':0,'W':0,'X':0,'Y':0,'Z':0,'.':0,',':0, 
     '1':0,'2':0,'3':0,'4':0,'5':0,'6':0,'7':0,'8':0,'9':0,'0':0, '-':0,'(':0, ')':0} 

    for k, v in dct.items(): 
     for i in mylst: 
      if i == k: 
       dct[k] += 1 
       up_dct = sorted(dct.items(), key=operator.itemgetter(1), reverse=True) 

    srt_dct = dict((k, v) for k, v in up_dct) 

    return srt_dct 


def assign_code(nodes, label, result, prefix = ''): 
    childs = nodes[label] 
    tree = {} 
    if len(childs) == 2: 
     tree['0'] = assign_code(nodes, childs[0], result, prefix+'0') 
     tree['1'] = assign_code(nodes, childs[1], result, prefix+'1') 
     return tree 
    else: 
     result[label] = prefix 
     return label 

def Huffman_code(_vals): 
    vals = _vals.copy() 
    nodes = {} 
    for n in vals.keys(): # leafs initialization 
     nodes[n] = [] 

    while len(vals) > 1: # binary tree creation 
     s_vals = sorted(vals.items(), key=lambda x:x[1]) 
     a1 = s_vals[0][0] 
     a2 = s_vals[1][0] 
     vals[a1+a2] = vals.pop(a1) + vals.pop(a2) 
     nodes[a1+a2] = [a1, a2] 
    code = {} 
    root = a1+a2 
    tree = {} 
    tree = assign_code(nodes, root, code) # assignment of the code for the given binary tree 
    return code, tree 

r_file = open('test.txt', 'r') 

ro = r_file.read() 


lst = list(ro) 

freq = getFreq(lst) 

code, tree = Huffman_code(freq) 

encoded = ''.join([code[t] for t in ro]) 
print('Encoded text:',encoded) 

w_file = open('encrypt.txt','wt') 
w_file.write(encoded) 
w_file.close() 

d_file = open('encrypt.txt', 'r') 

dec_ode = d_file.read() 

decoded = [] 
i = 0 
while i < len(dec_ode): # decoding using the binary graph 
    ch = dec_ode[i] 
    act = tree[ch] 
    while not isinstance(act, str): 
     i += 1 
     ch = dec_ode[i] 
     act = act[ch] 
    decoded.append(act) 
    i += 1 


test2_file = open('decode.txt', 'wt') 
test2_file.write(''.join(decoded)) 

test2_file.close() 

print('Decoded text:',''.join(decoded)) 
+0

は、あなたはバイトシーケンスではなく、文字列をエンコードすることになっていませんか? –

+1

ステップ1は、スラッシュの方向を正しく取得することです。 '\ n'、' \ t'などで、スラッシュではなくバックスラッシュを使用します。 – user2357112

+1

また、バイトをエンコードする場合は、その怪物の辞書の初期化を取り除きます。 'dct = [0] * 256'のようなものを使います。配列インデックスはバイト値になります。 –

答えて

1

代わりにgetFreq機能としてこれを試してみてください:

def getFreq(mylst): 
    counters = [0 for _ in range(256)] 
    for c in mylst: 
     counters[ord(c)] += 1 
    return { chr(c): v for c, v in enumerate(counters) } 

をあなたはバイトではなく、個別の文字として文字のリストを表示する必要があります。この関数は、入力文字を対応するASCII値に変換し、それを使用してカウンタのリストにインデックスを付けます。たとえば、aが出現するたびに、countersの97番目の要素がインクリメントされます。その後、すべての文字がカウントされた後に、countersはプログラムが予期しているようにdictに変換されます。

+0

IndexError:listインデックスを範囲外にスローします。それは文字や値の位置を変えてしまうので、他の場所でその辞書の使い方を駄目にする –

関連する問題