簡體   English   中英

字謎的字符串匹配

[英]String matching for anagrams

我有一些數據,就像(x,y,TEXT) ,它是將在給定(x,y)位置顯示在屏幕上的字符串的表示。 TEXT還包含用於顏色和字體數據的控制字符,以及其他控制字符(目前已忽略)。 我解析了所有控制字符的顏色,字體,大小和其他,最后只保留了字母數字內容。

這些數據是由一個場景的應用程序生成的(使用一個不錯的GUI,但是現在我不在乎),因此有不止一個這樣的條目構成了一個最終的場景。 例如: (6, 1, "Berlin") (10,2 , "Hauptbahnhof") (6, 1, "Berlin")(10,2 , "Hauptbahnhof")將給出最終的場景,看起來或多或少像(想象下面的圖形作為信息屏幕):

 0123456789....
0+----------------+
1|     Berlin     |
2|  Hauptbahnhof  |
3+----------------+

現在,該應用程序以完全不可預測的(和不可控制的,封閉的源應用程序)順序為最終場景生成對象,因此最終場景要么是第一個場景,要么是第二個場景。

  • (6, 1, "Berlin") (10, 2, "Hauptbahnhof") 我最終得到-> BerlinHauptbahnhof
  • (10, 2, "Hauptbahnhof") (6, 1, "Berlin") (10, 2, "Hauptbahnhof") (6, 1, "Berlin") 我最終得到-> HauptbahnhofBerlin

可能有數十個(x,y,TEXT)條目代表一個場景,其中有些甚至只有一個字符(例如:每個字母都以不同的顏色打印,或者這些字符放在屏幕的對角線旁邊,或以波形形式)。

對於解釋這些數據的硬件設備而言,也不重要,因為所有文本都將在正確的位置顯示在屏幕上。

但是...我應該將場景中的全文與以下final一項匹配: Berlin Hauptbahnhof ,對我來說是p(l)aintext。 因此,現在我需要提出一種返回校驗和/哈希的算法,而不是依賴於順序或字符,這使我得到與字符串混亂的final結果相同的結果。

舉個例子:

"This is a fox"應當給予同樣的"a fox This is" (只是字被弄亂)和"T hisisafox" (所有字符都是從不同的塊,可以不同的顏色),但不一樣的"This is a pex"'e' 'f'少一個, 'p''o'一個,因此在這種情況下,簡單的加法校驗和將失敗)。 合並/排序它們也不是一種選擇,因為在這種情況下,“吃大魚”將等同於“袋裝小偷是”(即:字謎會得出相同的結果)。

那我還有其他選擇嗎?

一種抽象的思考方式是,您實際上是在對單詞的直方圖進行哈希處理。

在這種情況下,直方圖只是一組對<word, count> 如果您采用將這些對按單詞排序的約定,則直方圖表示就是規范的,您可以使用任何您喜歡的標准哈希函數來獲取與訂單無關的哈希碼。

例如,在Java中,您可以構建一個HashMap映射詞來計數,然后獲取此映射的hashcode

因此,剩下的問題是如何檢測輸入中的單詞。 您的示例似乎相互矛盾,但是我假設一個或多個空格表示一個單詞中斷。

@Kevin的模擬屏幕生成的方法是一種方法。 在每個屏幕繪畫的末尾,您都可以累積單詞。

另一個如下:維護一個間隔樹數組,每個屏幕行一個,每個間隔還存儲它代表的文本。 通過將新基准(x,y,文本)插入到間隔樹中來對其進行處理。

如果在插入過程中發現間隔彼此相鄰,請連接它們,包括它們包含的字符串。 (這非常類似於在free操作期間在內存分配器中合並空閑塊。)

在任何時候,每個間隔樹都會在每一行上列出單詞。 因此,您可以隨時使用它們來查找上述可哈希的直方圖。

如果可以訪問(x, y, text)數據,則可以創建一個模擬硬件屏幕的Screen類。 然后,您可以通過比較兩個屏幕的字符串表示形式來檢查兩個屏幕是否相等。

示例Python實現:

class Screen:
    """emulates the hardware screen"""
    def __init__(self, data=None):
        """initialize state with some sensible values"""
        self.data = {}
        self.width = 0
        self.height = 0
        if data != None:
            for x, y, word in data:
                self.put_message(x, y, word)
    def put_message(self, x, y, message):
        """puts a message on the screen, adjusting the height/width to fit if necessary"""
        self.height = max(self.height, y+1)
        self.width = max(self.width, x + len(message))
        for idx, c in enumerate(message):
            self.data[(x+idx, y)] = c
    def __repr__(self):
        """returns a string which represents the contents of the screen"""
        ret = ""
        for y in range(1, self.height):
            row = "\n"
            for x in range(self.width):
                #fetch the character at this position, or a period if none exists
                row = row + self.data.get((x,y), ".")
            ret = ret + row
        return ret

def compare(first, second):
    print first
    print second
    if str(first) == str(second):
        print "\nThese are equal."
    else:
        print "\nThese are not equal."

data_a = [(6, 1, "Berlin"), (2, 2, "Hauptbahnhof")]
a = Screen(data_a)

data_b = [(2, 2, "Hauptbahnhof"), (6, 1, "Berlin")]
b = Screen(data_b)

data_c = [(0, 1, "This is"), (1, 2, "a fox")]
c = Screen(data_c)

compare(a, b)
compare(a, c)

結果:

......Berlin..
..Hauptbahnhof

......Berlin..
..Hauptbahnhof

These are equal.

......Berlin..
..Hauptbahnhof

This is
.a fox.

These are not equal.

在這里,我們看到ab具有相同的輸出,即使它們的輸入具有不同的順序。 而且c顯然不等於它們中的任何一個。

暫無
暫無

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

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