串的任何元件的第一次出現我有一個問題:我需要在字符串S1找到從字符串S2(或炭的陣列)的任何符號第一次出現。查找其他字符串
是否有用於此目的的標準功能?如果沒有,這個問題有什麼好的實現? (當然,我可以運行的indexOf從我的每S2字符,但這個開不似乎是一個很好的算法,因爲如果在S1只發生在最後一個符號,我們必須通過S1運行| S2 | -1次我纔得到答案)。
非常感謝!
串的任何元件的第一次出現我有一個問題:我需要在字符串S1找到從字符串S2(或炭的陣列)的任何符號第一次出現。查找其他字符串
是否有用於此目的的標準功能?如果沒有,這個問題有什麼好的實現? (當然,我可以運行的indexOf從我的每S2字符,但這個開不似乎是一個很好的算法,因爲如果在S1只發生在最後一個符號,我們必須通過S1運行| S2 | -1次我纔得到答案)。
非常感謝!
把所有字符從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)
。
您在尋找的是來自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;
}
線性搜索?噢,最好確保'searchChars'永遠不會很大。我認爲Apache會做一些更復雜的事情。 –
什麼是符號在這種情況下是什麼意思?如果它只是一個16位Java char
,那很簡單。爲所有可能的值創建一個查找表(數組),指出它們是否出現在s2中。然後通過s1,直到找到s2中的符號或者到達s1的末尾。如果一個符號是一個Unicode代碼點,它更復雜,但上面給出了一個方法來找出你需要仔細看看。
你的意思是,你將初始化一個2^16布爾數組,其中只有對應於s2中的一個字符的元素被設置爲true? (有趣的想法;我認爲HashSet可以執行得幾乎一樣) –
@AndreHolzner是的,這就是主意。2^16足夠小,所以不需要使用像HashSets這樣的花哨的東西,簡單的數組就可以做到。我對JVM不夠熟悉,但在C中,我相當確信它的速度更快,因爲它適合於L2(正常硬件)。如果字符數爲20或更多,那麼數組將變得太大,所以肯定是某種集合。 –
鑰匙的領域是小2^16所以這是一個很好的答案。 – javadba
使用正則表達式:
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());
}
}
在編譯模式之前,您應該避開特殊字符,例如使用'Pattern.quote(..)',請參閱http://stackoverflow.com/questions/60160/how-to-escape-text-for-regular-expression-in-java –
是的,這個答案可能需要一個公平的增加的數量要強勁。包含連字符的字符串也會導致我認爲的一些問題。 –
不是; Java String類沒有這樣的東西。你能想象一個比你描述的更好的算法嗎? – maerics
我會將字符串s2的字符打包到[正則表達式]中(例如http://download.oracle.com/javase/1.4.2/docs/api/java/util/regex/Pattern.html)。 'a | b | c | d'(必須轉義特殊字符),然後使用Matcher.find(..)獲取第一個匹配項。 –
@maerics我懷疑它更快。使用這樣的正則表達式,只需要在字符串中迭代一次。 – Paulpro