作为一个爱好项目,我想用C ++和Python(两者)实现摩尔斯电码编码器和解码器。我想知道我应该使用的正确的数据结构。这个问题不仅与这个特定的项目有关,而且一般来说,当必须进行预定义的文本替换时,最好和最快的方法是什么?
如果可能的话,我会避免重新发明任何数据结构(我认为是这样)。请注意,这纯粹是一个学习练习,我一直想知道这样做的最佳方法是什么。我可以将代码和相应的字符存储在字典中,然后迭代文本并进行替换。这是最好的方式,还是我可以做得更好?
答案 0 :(得分:3)
from collections import defaultdict
morsecode = [('a','._'), ('b','_...'), ('c','_._.')]
codedict = defaultdict(lambda:' ')
for k,v in morsecode:
codedict[k] = v
tomorse = lambda x: ' '.join([codedict[chr] for chr in x])
print tomorse('bab cab')
给予:
_... ._ _... _._. ._ _...
答案 1 :(得分:2)
在Python中,字符串是不可变的,因此可能(取决于您对输出执行的操作),您希望创建所有简单替换结果的列表。类似的东西:
MORSE = {'A': '.-', ...}
def morsify(data):
return [MORSE[c] for c in data if c in MORSE]
如果您想支持不同国家版本的摩尔斯电码等,您需要获得相应的发车。
(编辑处理莫尔斯代码显然不是前缀代码的事实。)
答案 2 :(得分:2)
您可以使用str.translate
:
m = {ord('S'): '---', ord('O'): '...'}
print('S O S'.translate(m))
将打印:
--- ... ---
答案 3 :(得分:2)
在Python方面,字符串类'translate函数是要走的路。在C ++方面,我会使用std :: map来保存字符映射。然后我可能会使用std :: for_each进行查找和交换。
答案 4 :(得分:1)
没有简单的最优结构 - 对于任何给定的固定映射,对于精确映射可能存在恶劣的比特错误优化,在不同的体系结构和不同的输入上更好或更差。地图/字典应该一直很好,而且代码非常简单。
我的官方建议是坚持这一点。查找性能不太可能成为像这样的代码的问题,因为很可能你可以比输入/输出更快地编码/解码。
因为这是一个学习练习,你想尝试不同的可能性:对于文本 - >莫尔斯你可以使用数组而不是地图/字典。也许令人惊讶的是,这在C ++中很难做到并且完全可移植。以下假设所有大写字母的char
值大于A
,标准不保证:
std::string encode['Z'-'A'];
encode['A' - 'A'] = ".-";
encode['B' - 'A'] = "-...";
// etc.
encode['Z' - 'A'] = "--..";
如果您愿意假设您的代码只能运行在基本字符集具有连续运行字母的机器上(对于ASCII而不是EBCDIC),您可以稍微整理一下:
std::string encode[26] = {".-", "-...", /* etc */ "--.."};
查找存储在变量c
中的字符:
morse = encode[c - 'A'];
Python版本可以采用ASCII(我认为),你必须使用ord
。
要处理除大写字母以外的任何内容,您需要一个更大的数组(包含每个可能的char值的条目),或者需要带有边界检查的多个数组,标点符号的特殊情况代码等等。
答案 5 :(得分:1)
取决于文本的数量,'foo'.replace('f','..-。')。replace('o',' - ')将起作用。
除非你翻译成千上万行文本,否则你可能不会注意到你使用的任何方法都有很大差异 - 尽管你可以轻松地使用timeit模块来测试每种不同的方法。
答案 6 :(得分:0)
Python(需要一个字符串):
def m(t):
m=0xBFAFA7AEA1A0B0B8BCBE121A021D11120C41888A642082668040876584434267868D626021618163898B8C
r=[]
for c in t.upper():
val=int((m/(256**(90-ord(c))))%256)
r.append("".join([str((val>>y)&1) for y in range(val/32-1,-1,-1)]))
return " ".join(r)