あなたの方法は実際にはテキストファイルを効率的に圧縮する方法ではなく、既存のzlibを使用するだけです。
しかし、学問的な演習では、pickleを使用して辞書キーを保存し、それを復元するときに同じ値が得られるようにすることができます。呼び出し間に '圧縮された'形式が存在するように、以前に圧縮されたファイルを正常に解凍できるようにするには、各単語にインデックスを割り当てる必要があります。 '標準'のPythonメソッドを使用する場合は、コレクションからのOrderedDictを使用してインデックスを作成することができます。新しい単語は最後に追加されますが、従来のdictオブジェクトとは異なり、古いものはその位置を保持します。より良い方法はOrderedSetですが、これは標準のPythonではありません。this recipeを参照してください。
ケース
あなたはまた、「この」、「この」かどうかを判断する必要があると「これは」別の単語や同じ言葉です。おそらく各単語トークンは、各文字が小文字か大文字かを示すビットフィールドを必要とする。 'ThIs'はトークン15を取得しますが、ビットフィールドは5 "0x1010"で、圧縮ファイルに(15,5)のタプルが生成されます。
句読点
また、単語は、このようにあなたは、圧縮された形で句読点文字のトークンを、これを表現する方法が必要になります中断された句読点を、検討する必要があります。 しかし、これに問題があります。 その後、解凍すると正確にオリジナルを再作成する必要がありますので、句読点を処理してください。例えば"これは正しいです?" - > [1,2,3,4] - > "これは正しいですか?"または「これは正しいですか?」スペースなしで。 句読点ごとに前後の文字にどのように結合するかを指定する必要があります。 句読点はたった1文字(つまり1つの8ビットの数字)であるため、文字をそのまま置くことを検討するとよいでしょう。
複数のスペースが
また、複数のスペースを処理する必要があります。
例コード
このコードは、主にテストされていない不完全であり、おそらく、すべてのユースケースを処理しませんが、質問に対する一つの可能な解決策を示しています。 のpython compdict.py -c in.txt out.comp または のpython compdict.py -d out.compを実行し、それを使用しますが、圧縮したいテキストを含むin.txtというファイルを作成するには
out.txt または python compdict。py --list
from ordered_set import OrderedSet #pip install ordered_set
import os
import cPickle as pickle
import string
import argparse
class CompDecomp(object):
__DEFAULT_PICKLE_FN__ = "my.dict"
printable_non_chars = set(string.printable) - set(string.digits) - set(string.ascii_letters)
def __init__(self, fn=None, *args, **kw):
if fn is None:
self.fn = self.__DEFAULT_PICKLE_FN__
else:
self.fn = fn
self.dict = self.loaddict()
def loaddict(self):
if os.path.exists(self.fn):
pkl = open(self.fn, "rb")
d = pickle.load(pkl)
pkl.close()
else:
d = OrderedSet()
return d
def savedict(self):
pkl = open(self.fn, "wb")
pickle.dump(self.dict, pkl)
pkl.close()
def compressword(self, word, conjoin=False):
if word.lower() not in self.dict:
self.dict.append(word.lower())
print "New word: \'%s\'" % word
self.savedict()
index, flag, _ = self.__caseflag__(word, conjoin)
#print index, bin(flag)[2:].zfill(len(word)), conjoin
return index, flag, conjoin
def decompressword(self, index, caseflag=0, conjoin=False):
if isinstance(index, int):
word = self.dict[index]
else:
word = index
if caseflag == 0:
return word, conjoin
flag = bin(caseflag)[2:].zfill(len(word))
res = ""
for n, c in enumerate(word):
if flag[n] == '1':
res += c.upper()
else:
res += c.lower()
return res, conjoin
def __caseflag__(self, word, conjoin):
index = self.dict.index(word.lower())
if word.lower() == word:
#Word is all lowercase
return (index,0, conjoin)
if word.upper() == word:
#Word is all uppercase
return index, int("1" * len(word), 2), conjoin
res = ""
for c in word:
if c in string.uppercase:
res += "1"
else:
res += "0"
return index, int(res, 2), conjoin
def compressfile(self, fileobj):
with fileobj as f:
data = f.read(-1)
f.close()
words = data.split(" ")
compress = []
for word in words:
#Handle multiple spaces
if word == "":
compress.append(" ")
continue
#Handle puntuation, treat apostrophied words as new words
substr = []
p1 = 0
csplit = word.translate(None, string.ascii_letters+'\'')
for n, c in enumerate(csplit):
subword, word = word.split(c, 1)
compress.append(self.compressword(subword, True if n > 0 else False))
compress.append((c, 0, True))
#Handle words
if len(word) and not len(csplit):
compress.append(self.compressword(word))
return compress
def decompressfile(self, fileobj):
data = pickle.load(fileobj)
decomp = ""
for v in data:
if not isinstance(v,tuple):
print "Bad data %s" % v
continue
if len(v) > 0 and len(v) <= 3:
d, conjoin = self.decompressword(*v)
if len(decomp):
decomp += "" if conjoin else " "
decomp += d
else:
print "Bad data %s (length %d)" % (v, len(v))
return decomp
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='Test file compress/decompress')
group = parser.add_mutually_exclusive_group()
parser.add_argument('infile', nargs='?', default=None)
parser.add_argument('outfile', nargs='?', default=None)
group.add_argument('-compress', action='store_true')
group.add_argument('-decompress', action='store_true')
group.add_argument('--list', action='store_true')
args = parser.parse_args()
cd = CompDecomp()
#Invocation
#python dictcompress.py [-h|-c|-d|--list] [<infile>] [<outfile>]
infile, outfile = args.infile, args.outfile
if infile is not None and not os.path.exists(infile):
print "Input file missing"
if outfile is not None:
of = open(outfile, "wb")
else:
of = None
if not args.list:
if args.compress:
print "Compress"
pickle.dump(cd.compressfile(open(infile, "r")), of)
if args.decompress:
print "Decompress"
of.write(cd.decompressfile(open(infile, "r")))
else:
for k in cd.dict:
print k
if of is not None:
of.close()
「1」が「こんにちは」であり、「こんにちは」などの単語ではないことをプログラムがどのように知っていますか?あなたのコードも不完全です。 –
ファイルのどこかに、すべての番号が対応する単語を指定する必要があります。 – Keatinge
私のコードは不完全であると私は理解する。これは、ユーザー入力を読み込んで、その形式に変換します。そうであるかどうかは単なる例にすぎません。同じ列挙で繰り返し単語を読むことができます。私はこのコードを数字の出力を読んで単語に変換する助けが必要です。 –