求N个字符串中的最大公子串

本文探讨了如何在一组字符串中找到最大的公共子串,并提供了算法实现的详细步骤,包括分解最小字符串和匹配过程。通过实例代码演示了解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天在网上看到有一道算法题目:
求N个字符串中的最大公子串
[url]http://www.iteye.com/topic/1118325[/url]
刚好闲着,做之。
先说一下思路:
1、从N个字符串中找出最小的字符串
2、分解出最小字符串最大公字符串列表:
例如:abcde
--------------------
abcde
abcd
bcde
abc
bcd
cde
ab
bc
cd
de
----------------------
3、分解出来的公子串从上到下去匹配其他的字符,都能匹配成功则是所要查找的最大公子串
4、如果同时存在两个相等长度的公子串 则以最先发现的为最大

说完上代码:


import java.nio.Buffer;
import java.nio.CharBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/**
* 求N个字符串中的最大公子串
*思路:
* 1、从N个字符串中找出最小的字符串
* 2、分解出最小字符串最大公字符串列表:
* 例如:abcde
* --------------------
* abcde
* abcd
* bcde
* abc
* bcd
* cde
* ab
* bc
* cd
* de
* ----------------------
* 3、分解出来的公子串从上到下去匹配其他的字符,都能匹配成功则是所要查找的最大公子串
* 4、如果同时存在两个相等长度的公子串 则以最先发现的为最大
*
*/
public class MaxPublicStr {


class Combination {

private CharBuffer a(char[] a, int[] tempNum, int m, int n, int startInd) {
for (int i = 0; i < n; i++) {
if (i >= startInd && i < (m + startInd)) {
tempNum[i] = 1;

} else {
tempNum[i] = 0;
}
}
return createResult(a, tempNum, m);
}

/**
* @param a:组合数组
* @param m:生成组合长度
* @return :所有连续的组合数组列表
*/
public List<CharBuffer> combinationsequence(char[] a, int m) {
List<CharBuffer> list = new ArrayList<CharBuffer>();
int n = a.length;
// 生成辅助数组。首先初始化,将数组前n个元素置1,表示第一个组合为前n个数。
int[] tempNum = new int[n];
for (int i = 0; i < tempNum.length; i++) {
if (i + m > n) {
break;
}
list.add(a(a, tempNum, m, n, i));
}
return list;
}

// 根据辅助数组和原始数组生成结果数组
@SuppressWarnings("unchecked")
public CharBuffer createResult(char[] a, int[] temp, int m) {
CharBuffer bos = CharBuffer.allocate(m);
for (int i = 0; i < a.length; i++) {
if (temp[i] == 1) {
bos.put(a[i]);
}
}
return bos;
}

}

public List<CharBuffer> combinationsequence(String str, int m) {
char[] a = str.toCharArray();
Combination c = new Combination();
List<CharBuffer> list = c.combinationsequence(a, m);
return list;
}

//字符串列表中的最短字符串
public String minStr(List<String> strings) {
return Collections.min(strings, new Comparator<String>() {
public int compare(String str1, String str2) {
if (str1.length() < str2.length())
return -1;
else if (str1.length() == str2.length())
return 0;
else if (str1.length() > str2.length())
return 1;
return 0;
}

});
}

//判断字符串列表中的每个字符串是否包含指定字符串,如果有一个不包含就返回false
public boolean contains(List<String> strings, String str) {
for (String s : strings) {
if (!s.contains(str))
return false;
}
return true;
}

public String maxSubString(List<String> strings) {
String shortStr = minStr(strings);
int i = shortStr.length();
//i是1 而不是0 因为当只有一个字符串的时候就没最大可言
while (i > 1) {
List<CharBuffer> list = combinationsequence(shortStr, i);
for (CharBuffer charBuffer : list) {
Buffer tempstr = charBuffer.rewind();
if (contains(strings, tempstr.toString())) {
return tempstr.toString();
}
}
i--;
}
return null;
}

public static void main(String[] args) {
MaxPublicStr max = new MaxPublicStr();
ArrayList<String> strings = new ArrayList<String>(Arrays.asList("ababcdghy", "abcdeftdsfgsdg", "abcdefsdf"));
String publicStr = max.maxSubString(strings);
System.out.println(publicStr);

}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值