2010-09-15 20 views
3

作爲一個業餘愛好項目,我喜歡在C++和Python(兩者)中實現摩爾斯電碼編碼器和解碼器。我想知道我應該使用正確的數據結構。這個問題不僅與這個特定的項目有關,而且一般來說,當人們需要進行預定義的文本替換時,什麼是最好和最快的方式呢?C++和Python中的預定義文本替換

如果可能的話,我會避免重新創建任何數據結構(我認爲是這樣)。請注意,這純粹是一種學習練習,我一直在想什麼是做這件事的最好方法。我可以將代碼和相應的字符存儲在字典中,然後迭代文本並進行替換。這是做這件事的最好方式,還是我可以做得更好?

回答

1

有沒有簡單的結構優化 - 對於任何給定的固定映射,有可能是爲精確測繪魔王位變換的優化,是在不同的體系結構和不同的輸入或好或壞。地圖/字典應該一直很好,代碼非常簡單。

我的官方建議是堅持這一點。查找性能對於這樣的代碼來說不太可能成爲問題,因爲很可能你可以比輸入/輸出更容易編碼/解碼。

由於這是一個學習練習,你想嘗試不同的可能性:對於文本 - >莫爾斯,你可以使用數組而不是地圖/字典。也許令人驚訝的是,這在C++中很難做到,而且是完全可移植的。下面假設所有大寫字母比A更大char值,這是不按標準保證:

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

爲了配合比大寫字母其他任何東西,你需要使用一個更大的陣列(包含一切可能的字符值的條目),或者多個陣列與邊界檢查,標點符號特殊情況的代碼等。

+0

有趣的策略。感謝你的回答。 – user225312 2010-09-15 16:08:20

2

在Python中,字符串是不可變的,所以很可能(取決於你對輸出做什麼),你想創建一個所有簡單替換結果的列表。喜歡的東西:

MORSE = {'A': '.-', ...} 

def morsify(data): 
    return [MORSE[c] for c in data if c in MORSE] 

你需要得到,如果你想支持的莫爾斯電碼等不同國家的版本corresondingly票友

(編輯處理的事實,莫爾斯電碼顯然不是一個前綴代碼)

+0

你不能用一個空字符串連接 - 莫爾斯是不是一個前綴碼 - 但希望這並不重要,因爲提問者是頂那方面。 – 2010-09-15 14:24:18

+0

@Steve:莫爾斯*應該*是一個前綴代碼!根據我所知道的每一個來源,都是如此。 – 2010-09-15 15:05:51

+0

@Konrad:「E」是「。」 「T」是「 - 」。 「M」是「 - 」。 「O」是「---」。這就像代碼可能是非前綴一樣 - 除「E」和「T」之外的每個*符號都有一個符號前綴。操作員在字母之間留下暫停。 – 2010-09-15 16:31:41

1

Googlefirst hit

根據文本的數量, 'foo'.replace(' F '' ..-。 ')替換(' O」, '---')會工作。

除非你翻譯過數以千計的文本行的,你可能不會注意到一大堆的差異在您使用的任何方法 - 儘管你可以方便地使用timeit模塊來測試每個不同的方法。

+0

對於這種情況,我同意,速度應該不重要。但是,如果是這樣,我想知道它。 – user225312 2010-09-15 16:09:49

2

你可以使用str.translate

m = {ord('S'): '---', ord('O'): '...'} 
print('S O S'.translate(m)) 

會打印:

--- ... --- 
+0

僅限Python 3.x? – 2010-09-15 14:40:25

+0

我會閱讀。謝謝。 – user225312 2010-09-15 16:10:12

+0

不,但您必須進行一些轉換。在Python 2.6中,它有點複雜。 – Joschua 2010-09-15 16:20:40

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') 

給出:

_... ._ _... _._. ._ _... 
2

在Python端串類的翻譯功能是要走的路。在C++端,我會用std :: map去保存字符映射。然後,我可能會使用std :: for_each來執行查找和交換。

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)