我有一些数据,类似于(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会给出相同的结果)。
那么我还有其他选择吗?
答案 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.
在这里,我们看到a
和b
具有相同的输出,即使它们的输入具有不同的顺序。并且c
显然不会与其中任何一个相等。