给定一组字符串,比如说
ap***
ab*le
a****
ab***
问题是,在给定字符串数量和允许差异数量的情况下,找出一组字符串是否一致。
所以使用上面的设置,答案是“是”,如果我们允许一个不一致的字符串(第二个),但如果我们不允许不一致的字符串,则为“否”。
什么是最好的算法,什么是复杂性?
我提出的每一个解决方案要么需要查看每个组合,要么完全错误。例如,你不能只是通过并添加字符串到一个集合(定义为“不兼容”),因为**,ab ad将通过。
实际问题(来自): 问题M
在2417年,考古学家发现了大量20世纪重要文本的文本 - 重要的。尽管有许多重复的文件,但很快就会明白这一点 由于时间造成的损失使大部分文字难以理解,也有一些不同意见 - 他们之间的关系。但是,注意到可以使文本组保持一致,即 文本之间的一致性可以通过遗漏一些(少量)文本来实现。例如,文本:
ap***
ab*le
app*e
*p\**e
(其中*表示难以辨认的字符)可以通过仅删除第二个文本来保持一致。
输入将包含一系列文本。每组都以一行指定 集合中的文本数量,以及可以删除的最大文本数量。这将会 其次是各个文本,每行一个。每个文本至少包含一个,不超过一个 250个字符,小写字母或星号。一组中的所有文本都是相同的长度 并且一组中不会有超过10,000个文本。集合序列由一行终止 包含两个零(0 0)。
每组的输出包含一行,其中包含“是”或“否”之一,具体取决于 通过最多删除指定数量的文本来确定该集合是否一致。
Sample input
4 1
ap***
ab*le
app*e
*pple
3 1
a
b
c
4 2
fred
ferd
derf
frd*
0 0
Sample output
Yes
No
No
答案 0 :(得分:1)
这感觉像家一样,所以我要省略一些细节。
trie可以很好地处理这个问题。在给定文本包含*
的任何索引处,您将该文本从特里结构中的所有其他叶子下降。然后你走路,寻找匹配足够文本的任何终端节点。
trie最多有n * m
个节点,因此添加另一个文本O(nm)
。
构建特里结构也有一个复杂因素。您必须按正确的顺序添加文本,并且必须检查每个文本索引的正确顺序。否则,您最终可能会遇到*b
的终端节点中未包含ab
的情况。但这样做并没有引入任何进一步的算法复杂性。
总时间为O(mn^2)
。构建它后,将它移动O(nm)
,为O(nm)
节点添加节点为n
。
答案 1 :(得分:0)
我建议您使用字符串和计数表示一组一致的字符串。该字符串在一个位置有一个字母,其中集合中的任何字符串都有一个字母,否则有一个星号。 count是集合中的字符串数。所以{ab **,a * b *} = [abb *,2]。
从单个表示开始,[ * *,0]。
每次看到字符串X:
1)将[X,1]添加到表示集
2)如果它与目前为止的任何表示一致,则从字符串和表示创建一个新表示 - 增加计数,并在必要时在字符串中修复更多字母。将新表示添加到表示集。
3)如果现在有多个具有相同字符串的表示,则只保留一个,计数是该字符串的最大值。
4)删除其计数小于目前为止看到的字符串数量减去允许遗漏的字符串数量的表示。
5) - 从(1)重复下一个字符串
最后,最合理的答案(如果有的话)是计数最多的答案。将创建任何一致的答案。任何时候手头的最大表示数是该阶段可能的答案的最大数量,即选择(n,x),其中N是在该点看到的字符串数,x是您的文本数允许丢弃。如果x = 1,则这是n(n-1)/ 2。你必须这样做n次,而其他成本只会随着字符串的长度而增长,所以我猜你有一个O(mn ^ 3)算法。