字谜的字符串匹配

时间:2014-03-24 14:37:13

标签: string algorithm match hashcode checksum

我有一些数据,类似于(x,y,TEXT),它是字符串的表示形式,将在屏幕上放置在给定的(x,y)位置。 TEXT还包含颜色和字体数据的控制字符以及其他控制字符(暂时忽略)。我解析出颜色,字体,大小等所有控制字符,最后只保留字母数字。

这个数据是由一个场景的应用程序生成的(使用一个漂亮的GUI,但现在不是我关心的),因此有多个这样的条目组成一个最终场景。例如:(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")。我最终得到了 - > HauptbahnhofBerlin

可以有几十个(x,y,TEXT)条目代表一个场景,其中一些甚至只有一个字符(例如:每个字母都印有不同的颜色,或者字符放在屏幕的对角线旁边,或以波形形式)。

对于解释这些数据的硬件设备来说,它并不重要,因为所有文本都会在正确的位置进入屏幕。

但是......我应该将场景中的全文与final顺序匹配:Berlin Hauptbahnhof对我来说是p(l)aintext。所以现在我需要提出一个返回校验和/散列的算法,而不是依赖于顺序或字符,这给了我与final相同的结果,用于字符串混乱的有序字符。

举个例子:

"This is a fox"应该提供相同的"a fox This is"(只是单词被搞砸了)和"T h i s i s a f o x"(所有字符来自不同的块,可能是不同的颜色)但不一样{ {1}} "This is a pex"'e''f''p''o'少一个,因此对于这种情况,简单的加法校验和将失败)。合并/排序它们也不是一种选择,因为在那种情况下"吃大鱼"等于"包贼是" (即:anagrams会给出相同的结果)。

那么我还有其他选择吗?

2 个答案:

答案 0 :(得分:0)

一种抽象的思考方式是你真的要对单词的直方图进行哈希处理。

在这种情况下,直方图只是一组对<word, count>。如果采用这些对按字排序的约定,则直方图表示是规范的,您可以使用任何您喜欢的标准哈希函数来获得与顺序无关的哈希码。

例如,在Java中,您可以构建一个HashMap映射字来计算,然后获取此地图的hashcode

所以剩下的问题是如何检测输入中的单词。你的例子似乎互相矛盾,但我假设一个或多个空格意味着一个单词中断。

@ Kevin的模拟屏幕生成方法是一种方法。在每个屏幕绘画结束时,您可以累积单词。

另一个如下:维护一个interval trees数组,每个屏幕行一个,每个间隔也存储它代表的文本。通过将新数据(x,y,text)插入到间隔树中来处理它。

如果在插入过程中发现间隔彼此相邻,请将它们连接起来,包括它们包含的字符串。 (这非常类似于在free操作期间在内存分配器中合并空闲块。)

任何时候,每个间隔树都会列出每行的单词。因此,您可以随时使用它们查找上面的可清洗直方图。

答案 1 :(得分:0)

如果您有权访问(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显然不会与其中任何一个相等。