如何编写函数生成包含两字符串作为子串的最短合并字符串?
看起来你的函数只考虑了A的后缀与B的前缀重叠的情况,但漏掉了两种关键场景:一是其中一个字符串本身就是另一个的子串(这时候直接返回长的那个就行),二是B的后缀与A的前缀重叠的情况(这种场景下拼接后的字符串可能更短)。我们来一步步修正这个问题:
你的现有代码的问题
- 未处理子串包含场景:如果A本身就是B的子串,那最短的C就是B;同理如果B是A的子串,C就是A。你的代码没有做这个判断,会导致不必要的拼接(比如A='abc',B='cdeabc',你的代码会返回
abcdeabc,但正确结果是cdeabc)。 - 只单向考虑重叠:你的逻辑只遍历A找和B前缀的重叠,但反过来B的后缀和A前缀的重叠可能会产生更短的结果(比如例子3中
A='abc', B='cdeab',你的代码得到abcdeab,但正确的cdeabc是通过B的后缀ab和A的前缀ab重叠得到的)。
修正后的实现思路
我们需要分四步处理:
- 处理空字符串边界情况;
- 检查其中一个字符串是否是另一个的子串,是则直接返回长的那个;
- 计算两种方向的最大重叠长度:
- A的后缀与B的前缀的最大重叠长度;
- B的后缀与A的前缀的最大重叠长度;
- 生成两种拼接结果,返回较短的那个(长度相同则返回任意一个)。
完整代码实现
def get_shortest_superstring(A, B): # 处理空字符串边界情况 if not A: return B if not B: return A # 检查是否其中一个是另一个的子串 if A in B: return B if B in A: return A # 辅助函数:计算s1的后缀与s2的前缀的最大重叠长度 def max_overlap(s1, s2): max_len = 0 max_possible = min(len(s1), len(s2)) for k in range(1, max_possible + 1): if s1[-k:] == s2[:k]: max_len = k return max_len # 计算两种方向的最大重叠 overlap_ab = max_overlap(A, B) overlap_ba = max_overlap(B, A) # 生成候选结果 candidate1 = A + B[overlap_ab:] candidate2 = B + A[overlap_ba:] # 返回较短的那个,长度相同则返回任意一个(这里选candidate1) return candidate1 if len(candidate1) <= len(candidate2) else candidate2
测试你的示例
我们用你的例子验证:
A='abcd', B='cde'→ 返回abcde(正确)A='abcd', B='ecd'→ 返回abcdecd或ecdabcd(两者长度相同,正确)A='abc', B='cdeab'→ 返回cdeabc(正确)A='bce', B='eabc'→ 返回eabce(正确)A='', B='abc'→ 返回abc(正确)A='abc', B=''→ 返回abc(正确)
另外补充几个测试场景:
A='abcde', B='cde'→ 返回abcde(因为B是A的子串)A='abc', B='cdeabc'→ 返回cdeabc(因为A是B的子串)A='aaaaa', B='aaaaa'→ 返回aaaaa(两者互相包含)
内容的提问来源于stack exchange,提问作者sln
相关产品推荐
相关产品推荐

