簡體   English   中英

Python 中用二叉樹進行摩爾斯編碼

[英]Morse Encoding with Binary Tree in Python

我正在嘗試編寫一個使用二叉樹編碼/解碼摩爾斯電碼的程序。 最初我的代碼通過在運行時獲取輸入並成功將其轉換為摩爾斯電碼來工作。

但是,我試圖做到這一點,以便終端命令encode('xyz')將采用 xyz 字符串並轉換為摩爾斯電碼,並返回結果。 為此,我不得不重新調整代碼,現在遇到了錯誤。 有什么明顯的我想念的嗎?

class BTree: 
    def __init__(self, data=None, left=None, right=None):
        self.data = data
        self.left = left 
        self.right = right 

    def insert(self, data):
        if self.data:
            if data < self.data:
                if self.left:
                    self.left.insert(data)
                else: 
                    self.left = BTree(data) 
            elif data > self.data: 
                if self.right:
                    self.right.insert(data) 
                else:
                    self.right = BTree(data) 
        else:
            self.data = data

    def output(self): 
        if self.left:
            self.left.output() 
        print(self.data) 
        if self.right: 
            self.right.output() 

    def encode(self, msg: str):
        dotsdashes = []
        code = "".join(dotsdashes)

        for character in msg:
            self.getMorse(code, character, dotsdashes)
            morseCode = morseCode + code + " "

    def getMorse(self, node, character, code):
        if node==None:
            return False
        elif node.data == character:
            return True
        else:
            if self.getMorse(node.left,character,code) == True:
                code.insert(0,".")
                return True
            elif self.getMorse (node.right,character,code)==True:
                code.insert(0,"-")
                return True 

我的主要 function(復制並粘貼時格式不正確):

if __name__ == '__main__':
    root = BTree("Root")
    root.left = BTree("E")
    root.right = BTree("T")
    root.left.left = BTree("I")
    root.left.right = BTree("A")
    root.right.left = BTree("N")
    root.right.right = BTree("M")
    root.left.left.left = BTree("S")
    root.left.left.right = BTree("U")
    root.left.right.left = BTree("R")
    root.left.right.right = BTree("W")
    root.right.left.left = BTree("D")
    root.right.left.right = BTree("K")
    root.right.right.left = BTree("G")
    root.right.right.right = BTree("O")
    root.left.left.left.left = BTree("H")
    root.left.left.left.right = BTree("V")
    root.left.left.right.left = BTree("F")
    root.left.left.right.right = BTree("")
    root.left.right.left.left = BTree("L")
    root.left.right.left.right = BTree("")
    root.left.right.right.left = BTree("P")
    root.left.right.right.right = BTree("J")
    root.right.left.left.left = BTree("B")
    root.right.left.left.right = BTree("X")
    root.right.left.right.left = BTree("C")
    root.right.left.right.right = BTree("Y")
    root.right.right.left.left = BTree("Z")
    root.right.right.left.right = BTree("Q")
    root.right.right.right.left = BTree("")
    root.right.right.right.right = BTree("")

還想知道在主 function 而不是它自己的 function 中填充二叉樹是否正確?

我對使用二叉樹還比較陌生,所以對於可能解釋不當/愚蠢的問題深表歉意。

編輯:我應該包括我得到的最新錯誤是:第 41 行,在 getMorse elif node.data == character: AttributeError: 'str' object has no attribute 'data'

有這些問題:

  • morseCode = morseCode + code + " "中,您在賦值的右側引用morseCode ,但它從未用值初始化。 所以你需要在循環之前用空字符串初始化它

  • 在調用self.getMorse(code, character, dotsdashes)時,您傳遞一個字符串code作為第一個參數,但 function 需要一個節點。 所以你應該將self作為參數而不是code傳遞

  • self.getMorse返回一個 boolean,但在上面的調用中你永遠不會看到這個 boolean。當返回值為 false 時,你可能應該做一些事情。

  • code = "".join(dotsdashes)發生得太快了(而且只有一次)。 這應該在您調用self.getMorse之后在循環中發生,因為只有這樣才會填充dotsdashes

  • dotsdashes = []應該在每次調用self.getMorse之前發生,否則它只會將新的莫爾斯電碼累積到與上一次迭代已經擁有的電碼相鄰的位置。

  • encode應該返回結果。

這是該encode function 的更正:

    def encode(self, msg: str):
        morseCode = ""  # Init
        for character in msg:
            dotsdashes = []  # Moved inside the loop
            success = self.getMorse(self, character, dotsdashes) # Change first argument
            if not success:  # Deal with return value
                raise ValueError(f"Invalid character - no Morse code available for {character}")
            code = "".join(dotsdashes)  # Moved inside the loop
            morseCode = morseCode + code + " "
        return morseCode  # Return

評論:

  • 真的為此創建一棵樹似乎有點過分了。 字典似乎更合適:它需要更少的代碼,並且不需要遍歷樹來查找可能在任何地方的字符。
  • 將列表作為第三個參數傳遞給它填充的self.getMorse不是最佳做法。 更好的做法是將其作為返回值,如果沒有可用的摩爾斯電碼則返回None
  • insert方法實現了一個二叉搜索樹,這不是你在這里需要的。 它不應包含在您的 class 中。

替代樹

您創建的樹是一棵完整的二叉樹(甚至是完美的二叉樹),因此您可以在列表中對該樹進行編碼(就像對二叉堆所做的那樣)。 由於每個節點的數據只是一個字符,它可以是一個字符串而不是一個列表。

然后可以使該字符串中索引的二進制表示成為該索引處字符的摩爾斯電碼(其中 0,1 分別映射到點、破折號)。 為了確保所有二進制 0 都包含在二進制表示中,即使它們出現在任何 1 之前,我們可以將 go 用於二進制表示,其中第一個 1 被忽略,所有其他二進制數字代表實際的摩爾斯電碼。

這導致以下代碼,它仍然是基於樹的:

MORSE = "..ETIANMSURWDKGOHVF.L.PJBXCYZQ"

def encode_char(c):
    return bin(MORSE.index(c))[3:].replace("0", ".").replace("1", "-")

def encode(s):
    return " ".join(map(encode_char, s))

print(encode("SOS"))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM