我必须使用带有相应二进制代码的字符字典来解码1和0的字符串。字典设置如下:
self.codes = {'a': '00', 'h': '111', 'e': '110', 'l': '01', 'o': '10'}
代码是这样的,没有二进制代码是任何其他代码的前缀。目前我有这个功能来进行解码:
def decode(self, ciphertext):
start = 0
while start < len(ciphertext):
for k in self.codes:
res = ciphertext.find(self.codes[k], start)
if res == start:
decoded += k
start += len(self.codes[k])
return decoded
(其中密文=要解码的文本,self.codes =表示编码系统的字典)
不出所料,这真的很慢。有人能指出我为这种事情提供更有效的算法吗?
[编辑]感谢大家的好建议。我回家后会在几个小时内尝试实施它们。
答案 0 :(得分:2)
你可以这样做:
def __init__(self, ...):
...
self.codes = {'a': '00', 'h': '111', 'e': '110', 'l': '01', 'o': '10'}
self.decode_codes = {value: key for key, value in self.codes.items()}
def decode(self, ciphertext):
result = ''
chunk = ''
for c in ciphertext:
chunk += c
if chunk in self.decode_codes:
result += self.decode_codes[chunk]
chunk = ''
return result
既然你说在彼此的开头没有包含两个代码,这种方法就可以了。
答案 1 :(得分:1)
如果您翻转键和值,您的代码将运行得更快:
self.codes = {'00': 'a', '111': 'h', '110': 'e', '01': 'l', '10': 'o'}
现在你可以这样做伪代码:
ciphertext =您的密文(例如“001111100110”)
plaintext =“”
currenttoken =“”
1)将当前的密文位添加到currenttoken
的末尾2)self.codes是否包含currenttoken?
2a)如果是这样,将self.codes [currenttoken]添加到明文,currenttoken =“”
字典访问是O(1),O(1)超过字符串的长度是O(n)。
如果你还需要非翻新的键/值来快速加密字符串,那么我建议你有两个字典,一个用于快速编码以快速解码。
答案 2 :(得分:1)
这是一个使用反向字典的更有效的解码器。我试图尽可能多地计算一些东西。
codes = {'a': '00', 'h': '111', 'e': '110', 'l': '01', 'o': '10'}
# generate the reverse dictionary and min/max length from the above
decodes = dict((v, k) for (k, v) in codes.iteritems())
# can use dict comprehension for above in Python >= 2.7
lenrange = range(min(len(k) for k in decodes), max(len(k) for k in decodes) + 1)
# for Python 3, add here: lenrange = list(lenrange)
def decode(ciphertext):
start, plaintext = 0, []
plaintext_append = plaintext.append # for speed
while True:
for n in lenrange:
key = ciphertext[start:start+n]
if key in decodes:
plaintext_append(decodes[key])
start += n
break
else: # return result when code can't be found (usually at end)
return "".join(plaintext)
答案 3 :(得分:1)
我试图实现Blender的答案,并且不得不做出一些小改动:
codes = {'a': '00', 'h': '111', 'e': '110', 'l': '01', 'o': '10'}
decode_codes = {value: key for key, value in codes.items()}
def decode(ciphertext):
result = ''
chunk = ''
for c in ciphertext:
chunk += c
if chunk in decode_codes:
result += decode_codes[chunk]
chunk = ''
return result
def encode(plaintext):
return ''.join(codes[c] for c in plaintext)
print decode(encode("hello"))