我有一个相当大的数字(1000s)的字符串,比如说S_1 ... S_n,其中字符只有2个值 - 比如说易于可视化“”(空格)或“_”(下划线)。
S_1: _______ ____ __ _____ ___
S_2: _______ _____ ___
S_3: _____________
S_4: ____ _____________
posi- 01234567890123456789012345...
tion 0 1 2
我想找到最长的拉伸,其中2个(或更多)字符串共享相同的连续长度的下划线。在上面的例子中,它是S_3和S_4之间从7到15位的共享部分,包括9个位置。
是否有一种有效的算法可以让我找到执行此操作的字符串对(或更多)?我不认为它是完全一个字符串匹配的东西,比如最长的常见子字符串问题,因为这些字符串具有特定的对齐方式。
注意,对于它的价值而言,这只是一个较大算法的一小部分,它重复这样做,将共享长度合并在一起形成一个新的字符串,以便在下一次迭代中,我会< / p>
S_1: _______ ____ __ _____ ___
S_2: _______ _____ ___
S_3: ____
S_4: ____ ___
S_N+1: _________
然后我会重复算法找到(在这种情况下)S_2,并且新的S_N + 1共享下一个最长的部分,从11-15位,形成
S_1: _______ ____ __ _____ ___
S_2: _______ ___
S_3: ____
S_4: ____ ___
S_N+1: ____
S_N+2: _____
然后是S_1,S_2,&amp; S_3从位置3-6共享一个部分,给出
S_1: ___ ____ __ _____ ___
S_2: ___ ___
S_3:
S_4: ____ ___
S_N+1: ____
S_N+2: _____
S_N+3: ____
等等
答案 0 :(得分:0)
首先,答案总是在2个字符串之间。如果这个&#34; 其中2个(或更多)字符串共享相同的连续下划线长度,则不可能有超过2个字符串,其序列长于匹配的最佳2个字符串。&#39 ;是正确的要求。 所以问题是找到在同一位置具有最长_序列的最长的2个字符串。要做到这一点,你必须这样做:
获取每个字符串并为每个_的桶创建另一个带有索引对的字符串 例如:对于_ ___ _____你的间隔数组将为[0,0],[2,4] [5,9]
取2个字符串的所有组合并取2个索引(i代表string1,j代表string2)。您需要做的是以智能方式移动每个索引。首先两者都是0,并且在每一步你都会问自己是否可以将索引i的间隔与索引j上的间隔相交,这样你就可以得到这两个间隔的最佳子序列。 完成交叉后,您有两个选项:增加i或增加j
一个。如果该区间在j区间的左侧
,则增加i湾如果该区间在i区间的左侧,则增加j。
℃。如果他们离开它是平等的,那么你增加的人并不重要。
优化: 1.对于每个区间数组,当你有2个字符串并且想要比较时,请记住最长的区间,如果其中一个字符串具有较小的“最大”字符串。间隔超过你不做算法的最大值,它不会提高最大值。
它的复杂性是O(N ^ 2 *(O(len(S1)+ len(S2)+ ... + len(Sn)))因为只有step1遍历所有字符。 2经历了间隔。
答案 1 :(得分:0)
我将假设所有字符串都是相同的长度,尽管您可以根据需要填充它们以使其工作。
有一个整数数组,A,与字符串长度相同,初始化为-1。 A [i]的值将是使用所有下划线从i到达的最大索引。也就是说,如果A [i] == k,那么有一些字符串使得该字符串中的A [i] .. k完全是下划线。
bestOverall := -1
For each string, S:
maxPos := -1
for i := len(S); i >= 0; i--:
if S[i] == '_' && maxPos < 0:
// We were previously look at ' ', now we're looking at '_', so store
// the highest index that happened at in this particular run.
maxPos = i
if S[i] == ' ':
maxPos = -1
if min(A[i]-i, maxPos-i) > bestOverall:
// This is the crux of it all. A[i]-i is the length of consecutive '_'
// you've seen in a single string before, starting at this position.
// maxPos-i is the length of consecutive '_' you've seen in this string,
// starting at this position. If this length is greater than your
// previous best, keep track of it. Presumably you also might want to
// store which strings were involved, which would take extra storage.
bestOverall = min(A[i]-i, maxPos-i)
if maxPos >= A[i]:
// If you're doing better with this string than previous iterations,
// keep track of it.
A[i] = maxPos
在这个最好的整体将是你可以用两个字符串得到的最长的下划线。您可以保留一个辅助数组来跟踪哪个是第一个涉及的字符串,并在每次更新时都存储第一个和第二个字符串。这是O(N * S),其中N是字符串的数量,S是字符串的长度。假设您的字符串采用这种格式而不是间隔列表,这是您可以做的最好的。如果它们确实是间隔列表,那么你可以做得更好。