第一行输入一个长度为
、仅由小写字母组成的字符串
。
第二行输入一个长度为
、仅由小写字母组成的字符串
。
输出一个字符串,代表
和
的最长公共子串。如果存在多个答案,输出在较短串中最先出现的那个。
awaabb aawbb
aa
在这个样例中,
和
都是
和
的最长公共子串,但
在较短串
中首先出现,因此输出
。
abcdefghijklmnop abcsafjklmnopqrstuvw
jklmnop
s1 = input() s2 = input() l1, l2 = len(s1), len(s2) if l1 > l2: s1, s2 = s2, s1 l1, l2 = l2, l1 # dp[i][j] ---> 最大公共子串得长度,该子串分别以s1[i-1]和s2[j-1]结尾 dp = [[0 for _ in range(1 + l2)] for _ in range(1 + l1)] max_len = -1 max_len_index_s1 = -1 for i in range(1, 1 + l1): for j in range(1, 1 + l2): if s1[i - 1] == s2[j - 1]: dp[i][j] = 1 + dp[i - 1][j - 1] if dp[i][j] > max_len: max_len = dp[i][j] max_len_index_s1 = i - 1 assert max_len >= 0 assert max_len_index_s1 >= 0 # print(max_len) # print(max_len_index_s1) print(s1[max_len_index_s1 + 1 - max_len : max_len_index_s1 + 1])
# 也是服了,存在多解时例子的答案只有一个就算了, # 关键还不是第一个找到的(在str1位置靠前的) # 以下动态规划代码,dp数组直接存储子串 """ 最长公共子串问题动态规划时关键在于状态的定义,比较巧妙 dp[i][j]表示以str1的第i个字符和str2的第j个字符结尾的公共子串。 注意,是以str1第i个字符和str2第j个字符结尾的公共子串, 如果str1第i个字符和str第j个字符不相等,那么不可能存在以它们结尾的公共子串。认为空字符'' 那么状态转移方程容易得出:如果str1第i个字符和str第j个字符相等, 那么dp[i][j]就是dp[i-1][j-1]+str1[i-1],因为多了一个公共字符, 如果str1第i个字符和str第j个字符不相等,那么以它们结尾的公共子串不存在,dp[i][j]='' """ def longest_common_substring(str1, str2): m = len(str1) n = len(str2) dp = [[""] * (n + 1) for _ in range(m + 1)] # 状态直接存储子串 for i in range(1, m + 1): for j in range(1, n + 1): if str1[i - 1] == str2[j - 1]: dp[i][j] = dp[i - 1][j - 1] + str2[j - 1] flattened_dp = [item for sublist in dp for item in sublist] # flattened_dp.reverse() return max(flattened_dp, key=lambda x: len(x)) import sys lines = [] for line in sys.stdin: line = line.strip() if line == "": break lines.append(line) str1, str2 = lines print(longest_common_substring(str1, str2))
a=input() b=input() if len(a)>len(b): a,b=b,a str='' for i in range(len(a)-1): for j in range(len(a),i+1,-1): if a[i:j] in b and len(a[i:j])>len(str): str=a[i:j] print(str)
# 暴力滑窗 str_i = input() str_j = input() if(len(str_i) > len(str_j)): str_i,str_j = str_j,str_i for i in range(len(str_i)-1): str_j = "\r"+str_j+"\r" max_len = 0 max_len_pos = -1 for j in range(len(str_j)-len(str_i)+1): temp_len = 0 for i in range(len(str_i)): if(str_i[i] == str_j[j+i]): temp_len += 1 if(temp_len > max_len): max_len = temp_len max_len_pos = i+1-temp_len elif(temp_len == max_len): head_pos = i+1-temp_len if(head_pos < max_len_pos): max_len_pos = head_pos else: temp_len = 0 #print(max_len_pos) for i in range(max_len): print(str_i[max_len_pos+i],end = "")
# -*- coding: utf-8 -*- """ @Time : 2023/5/19 08:25 @Author : Frank @File : HJ56.py HJ65 查找两个字符串a,b中的最长公共子串 描述 查找两个字符串a,b中的最长公共子串。若有多个,输出在较短串中最先出现的那个。 注:子串的定义:将一个字符串删去前缀和后缀(也可以不删)形成的字符串。请和“子序列”的概念分开! 数据范围:字符串长度 输入描述: 输入两个字符串 dp 问题 dp if str1[i - 1] == str2[j - 1] dp[i][j] = dp[i - 1][j - 1] + 1 else: dp[i][j] = 0 返回公共的字符串 可能有多个。 如下面的例子: 公共子串的长度是3,但是有两个不同的子串 gcn nlo nvlrzqcjltmrejybjeshffenvkeqtbsnlocoyaokdpuxutrsmcmoearsgttgyyucgzgcnurfbubgvbwpyslaeykqhaaveqxijc wkigrnngxehuiwxrextitnmjykimyhcbxildpnmrfgcnevjyvwzwuzrwvlomnlogbptornsybimbtnyhlmfecscmojrxekqmj """ def prepare_data(): str1 = input() str2 = input() return str1, str2 pass def lc_substr(str1, str2): n = len(str1) m = len(str2) dp = [[0 for j in range(m + 1)] for i in range(n + 1)] max_len = 0 index = 0 # 下标从1开始 for i in range(1, n + 1): for j in range(1, m + 1): # 注意这里 比较 i-1 and j-1 这个表示当前的字符 if str1[i - 1] == str2[j - 1]: dp[i][j] = dp[i - 1][j - 1] + 1 if dp[i][j] >= max_len: max_len = dp[i][j] index = i else: dp[i][j] = 0 return str1[index - max_len:index] if __name__ == '__main__': # s = 'abcde' # s2 = 'cde' s, s2 = prepare_data() # s = 'nvlrzqcjltmrejybjeshffenvkeqtbsnlocoyaokdpuxutrsmcmoearsgttgyyucgzgcnurfbubgvbwpyslaeykqhaaveqxijc' # s2 = 'wkigrnngxehuiwxrextitnmjykimyhcbxildpnmrfgcnevjyvwzwuzrwvlomnlogbptornsybimbtnyhlmfecscmojrxekqmj' print(lc_substr(s, s2))
a = input().strip() b = input().strip() if len(a) > len(b): temp = a a = b b = temp max_sub = '' for i in range(len(a)): for j in range(len(a), i, -1): if (a[i:j] in b) and (len(max_sub) < len(a[i:j])): max_sub = a[i:j] print(max_sub)
us1,us2 = input(),input() ll = [] if len(us1) > len(us2): us1,us2 = us2,us1 for _idx in range(len(us1) + 1): for j in range(_idx): _s = us1[j:_idx] if _s in us2: ll.append(_s) print(sorted(ll, key=len, reverse=True)[0])
def max_same_str(a,b): c=[] d=[] for i in range(len(a)): for j in range(i+1,len(a)+1): if a[i:j] in b: c.append(a[i:j]) d.append(len(a[i:j])) x=max(d) y=c[d.index(x)] print(y) while True: try: s1=input() s2=input() if len(s2)>len(s1): max_same_str(s1,s2) else: max_same_str(s2,s1) except: break
str1,str2 = input() ,input() total_list = [] if len(str1)>len(str2): str1,str2 = str2,str1 for i in range(len(str1)): for j in range(len(str1)): if j+i+1<len(str1): if str1[i:j+i+1] in str2: total_list.append(str1[i:j+i+1]) print(max(total_list,key=len)) 使用迭代思想对a进行切片,将包含在b中的所有切片放入一个列表,最后取出列表中长度最长的元素
#动态规划解题 def solution(a,b): dp = [[0 for i in range(len(a)+1)] for j in range(len(b)+1)] l_max = 0 for i in range(1,len(b)+1): for j in range(1,len(a)+1): if b[i-1] == a[j-1]: dp[i][j] = dp[i-1][j-1] + 1 if dp[i][j] > l_max : l_max = dp[i][j] #用于找出第一个出现的最长字串,必须在短串中找,所以得确定a,b的长短 for i in range(1,len(a)+1): for j in range(1,len(b)+1): if dp[j][i] == l_max: print(a[i-l_max:i])#注意dp中的i、j对应上字符时始终大1 return a,b= input(),input() #用于保证传入的参数,始终为短串在前、长串在后 temp = a a = a if len(b)>len(a) else b b = temp if len(temp)>len(b) else b solution(a,b)
while True: try: arr1 = input() arr2 = input() short, long = '', '' if len(arr1) < len(arr2): short = arr1 long = arr2 else: long = arr1 short = arr2 if short in long: print(short) else: for i in range(len(short)-1, 0, -1): for j in range(0, len(short)-i): arr = short[j:j + i + 1] if arr != '' and arr in long: print(arr) break else: continue else: continue break except: break