【发布时间】:2016-04-20 17:13:17
【问题描述】:
我遇到了一个问题语句来查找 给定两个子字符串之间的所有公共子字符串,这样在每种情况下您都必须打印最长的子字符串。问题陈述如下:
编写一个程序来查找两个给定字符串之间的公共子字符串。但是,不要包含包含在较长公共子字符串中的子字符串。
例如,给定输入字符串
eatsleepnightxyz和eatsleepabcxyz,结果应该是:
eatsleep(由于<b>eatsleep</b>nightxyz<b>eatsleep</b>abcxyz)xyz(由于eatsleepnight<b>xyz</b>eatsleepabc<b>xyz</b>)a(由于e<b>a</b>tsleepnightxyzeatsleep<b>a</b>bcxyz)t(由于eatsleepnigh<b>t</b>xyzea<b>t</b>sleepabcxyz)但是,结果集应该不包含来自的
e<b>e</b>atsleepnightxyzeatsl<b>e</b>epabcxyz,因为这两个es 都已经包含在上面提到的eatsleep中。你也不应该包括ea、eat、ats等,因为这些也都在eatsleep中。在此,您不必使用 String 实用方法,例如:contains、indexOf、StringTokenizer、split 和 replace。
我的算法如下:我是从蛮力开始的,当我提高基本理解时会切换到更优化的解决方案。
For String S1:
Find all the substrings of S1 of all the lengths
While doing so: Check if it is also a substring of
S2.
尝试找出我的方法的时间复杂度。
让给定的两个字符串分别为 n1-String 和 n2-String
- S1 的子串数显然是 n1(n1+1)/2。
- 但我们必须找到 S1 的子串的平均长度。
- 假设它是 m。我们将分别找到 m。
- 检查 m 字符串是否为子字符串的时间复杂度 n-String 是 O(n*m)。
- 现在,我们正在检查每个 m-String 是否是 S2 的子字符串, 这是一个 n2 字符串。
- 正如我们在上面看到的,这是一个 O(n2 m) 算法。
- 那么整个算法所需的时间是
- Tn=(S1 中的子串数)*(字符比较过程的平均子串长度)
- 通过执行某些计算,我得出的结论是 时间复杂度为 O(n3 m2)
- 现在,我们的工作是根据 n1 找到 m。
尝试根据 n1 找到 m。
Tn = (n)(1) + (n-1)(2) + (n-2)(3) + ..... + (2)(n- 1) + (1)(n)
其中 Tn 是所有子串的长度之和。
平均将是这个总和除以产生的子字符串的总数。
这个,简单来说就是一个求和除法问题,其解如下O(n)
因此...
我的算法的运行时间是 O(n^5)。
考虑到这一点,我编写了以下代码:
package pack.common.substrings;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
public class FindCommon2 {
public static final Set<String> commonSubstrings = new LinkedHashSet<String>();
public static void main(String[] args) {
printCommonSubstrings("neerajisgreat", "neerajisnotgreat");
System.out.println(commonSubstrings);
}
public static void printCommonSubstrings(String s1, String s2) {
for (int i = 0; i < s1.length();) {
List<String> list = new ArrayList<String>();
for (int j = i; j < s1.length(); j++) {
String subStr = s1.substring(i, j + 1);
if (isSubstring(subStr, s2)) {
list.add(subStr);
}
}
if (!list.isEmpty()) {
String s = list.get(list.size() - 1);
commonSubstrings.add(s);
i += s.length();
}
}
}
public static boolean isSubstring(String s1, String s2) {
boolean isSubstring = true;
int strLen = s2.length();
int strToCheckLen = s1.length();
if (strToCheckLen > strLen) {
isSubstring = false;
} else {
for (int i = 0; i <= (strLen - strToCheckLen); i++) {
int index = i;
int startingIndex = i;
for (int j = 0; j < strToCheckLen; j++) {
if (!(s1.charAt(j) == s2.charAt(index))) {
break;
} else {
index++;
}
}
if ((index - startingIndex) < strToCheckLen) {
isSubstring = false;
} else {
isSubstring = true;
break;
}
}
}
return isSubstring;
}
}
我的代码说明:
printCommonSubstrings: Finds all the substrings of S1 and
checks if it is also a substring of
S2.
isSubstring : As the name suggests, it checks if the given string
is a substring of the other string.
问题:给定输入
S1 = “neerajisgreat”;
S2 = “neerajisnotgreat”
S3 = “rajeatneerajisnotgreat”
在 S1 和 S2 的情况下,输出应为:neerajis 和 great
但在 S1 和 S3 的情况下,输出应该是:
neerajis、raj、great、eat 但我仍然得到neerajis 和great 作为输出。我需要弄清楚这一点。
我应该如何设计我的代码?
【问题讨论】: