假设我有 -
String x = "ab";
String y = "xypa";
如果我想查看y中是否存在x的任何子集,那么最快的方法是什么?循环耗时。在上面的例子中,x的子集是“a”,它在y中找到。
答案 0 :(得分:2)
答案真的取决于许多事情。
如果你只是想找到任何子集而你只做了一次,那么循环就可以了(并且你可以做到最好而不需要使用额外的存储空间),你可以在找到它时停下来匹配的单个字符。
如果您有一个固定的x
,并希望将其用于匹配多个字符串y
,则可以执行一些预处理,将x
中的字符存储在表格中并使用此表格用于检查y
中的每个字符是否出现在x
中。
如果您想找到最大子集,那么您正在查看另一个问题:longest common subsequence problem。
答案 1 :(得分:1)
嗯,我不确定它比循环更好,但你可以使用String#matches
:
if (y.matches(".*[" + x + "]+.*")) ...
您需要转义正则表达式[]
构造中特殊的字符(例如]
,-
,\
,...)。< / p>
以上只是一个示例,如果您不止一次这样做,则需要使用Pattern
,Matcher
以及java.util.regex
package中的其他内容。
答案 2 :(得分:0)
循环很耗时,但除了重复遍历目标字符串之外,没有办法做你想做的事。
您可以做的是先通过检查最小的字符串进行优化,然后逐步提升。例如,如果目标字符串不包含abc
,则它不可能包含abcdef
。
我的其他优化:
答案 3 :(得分:0)
你必须使用for循环或使用与for循环一样昂贵的正则表达式,因为你需要将你的一个字符串基本上转换为字符。
Boolean isSubset = false;
for(int i = 0; i < x.length(); i++) {
if(y.contains(x.charAt(i))) {
isSubset = true;
break;
}
}
使用for循环。
答案 4 :(得分:0)
看起来这可能是longest common substring problem的情况。
答案 5 :(得分:0)
你可以生成x的所有子集(例如,在你的例子中,ab,a,b),然后生成一个可以执行
的正则表达式 Pattern p = Pattern.compile("(ab|a|b)");
Matcher m = p.matcher(y);
if(m.find()) {
System.err.println(m.group());
}
答案 6 :(得分:0)
如果两个字符串只包含[a-z]
。然后最快的是制作两个位图,26位长。标记字符串中包含的所有位。获取位图的AND
,结果位出现在两个字符串中,这是最大的公共子集。这将是一个简单的O(n)
,其中n
是最大字符串的长度。
(如果你想覆盖整个UTF,布隆过滤器可能更合适。)
答案 7 :(得分:0)
这个怎么样??
package so3935620;
import static org.junit.Assert.*;
import java.util.BitSet;
import org.junit.Test;
public class Main {
public static boolean overlap(String s1, String s2) {
BitSet bs = new BitSet();
for (int i = 0; i < s1.length(); i++) {
bs.set(s1.charAt(i));
}
for (int i = 0; i < s2.length(); i++) {
if (bs.get(s2.charAt(i))) {
return true;
}
}
return false;
}
@Test
public void test() {
assertFalse(overlap("", ""));
assertTrue(overlap("a", "a"));
assertFalse(overlap("abcdefg", "ABCDEFG"));
}
}
如果该版本太慢,您可以根据s1
计算BitSet,将其保存在某个变量中,稍后只循环s2
。