我遇到问题:我需要在字符串 s1 中找到字符串 s2 (或字符数组)中任何符号的第一次出现
为此目的是否有标准功能?如果没有,那么这个问题的良好实施是什么? (当然我可以为我的s2中的每个字符运行 indexOf ,但这似乎不是一个好算法,因为如果只有最后一个符号出现在 s1 中,我们在得到答案之前,必须经过 s1 | s2 | -1 次。)
非常感谢!
答案 0 :(得分:5)
将s2
中的所有字符放入常量查找数据结构(例如HashSet
)。迭代s1
中的每个字符,看看你的数据结构是否包含该字符。
粗略(未经测试):
public int indexOfFirstContainedCharacter(String s1, String s2) {
Set<Character> set = new HashSet<Character>();
for (int i=0; i<s2.length; i++) {
set.add(s2.charAt(i)); // Build a constant-time lookup table.
}
for (int i=0; i<s1.length; i++) {
if (set.contains(s1.charAt(i)) {
return i; // Found a character in s1 also in s2.
}
}
return -1; // No matches.
}
此算法为O(n)
,与您描述的算法中的O(n^2)
相对。
答案 1 :(得分:4)
使用正则表达式:
public static void main(final String[] args) {
final String s1 = "Hello World";
final String s2 = "log";
final Pattern pattern = Pattern.compile("[" + Pattern.quote(s2) + "]");
final Matcher matcher = pattern.matcher(s1);
if (matcher.find()) {
System.out.println(matcher.group());
}
}
答案 2 :(得分:3)
您正在寻找的是来自Apache StringUtils的indexOfAny
。
看起来实现是:
public static int indexOfAny(String str, char[] searchChars) {
if (isEmpty(str) || ArrayUtils.isEmpty(searchChars)) {
return -1;
}
for (int i = 0; i < str.length(); i++) {
char ch = str.charAt(i);
for (int j = 0; j < searchChars.length; j++) {
if (searchChars[j] == ch) {
return i;
}
}
}
return -1;
}
答案 3 :(得分:3)
在此上下文中符号的含义是什么?如果它只是一个16位Java char
,那很简单。为所有可能的值创建一个查找表(数组),指示它们是否出现在s2中。然后逐步执行s1,直到您从s2找到符号或者您已到达s1的末尾。如果符号是Unicode代码点,那么它会更复杂,但上面提供了一种方法来找出您需要仔细查看的位置。