[英]String-matching first n letters of two strings
所以对于一个我面临的问题,我想知道一个序列(从索引0开始)两个字符串“相同”有多长时间-我想举一个例子会更清楚。
除了仅迭代两个单词之外,还有其他(省时)高效的方法吗? 我可以利用某种内置方法吗? (对于我的任务,我想避免导入任何自定义库)
我认为最快的方法是使用Binaray Search ,它将为您提供O(logn)复杂度,而不是O(n)。 这里n是最小字符串的长度。
该方法在二进制搜索中很简单。 在两个字符串中寻找索引字符的相似性结尾。 例如,如果i是您的索引,则检查i + 1以查找不相似字符,其中i索引处的字符相似。 如果是这种情况,请返回i作为您的答案。 否则继续在子范围内搜索。
编辑
增加功能以便更好地理解。
int lengthOfFirstSimilarCharacters(String str1, String str2) {
int strlen1 = str1.length();
int strlen2 = str2.length();
if(strlen1 > strlen2){
return lengthOfFirstSimilarCharacters(str2,str1);
}
int i = 0;
int j = strlen1-1;
while(i<=j){
int mid = i + (j-i)/2;
if(str1.charAt(mid) == str2.charAt(mid)) {
if(mid+1<strlen1 && str1.charAt(mid+1) != str2.charAt(mid+1)){
return mid+1;
}
i = mid+1;
}else{
j = mid-1;
}
}
return i;
}
您不必遍历两个文本。 遍历较小的那个并比较相同索引处的字符。 当发现不匹配时中断
String a ="Yellow";
String b= "Yelling";
String smaller = (a.length < b.length) ? a:b;
int ret =0;
for (index based on smaller ){
compare character using charAt and if matching ret++, else break;
}
return ret;
//如果希望不区分大小写,请使用charAt和equalsIgnoreCase一起使用。 String.valueOf(a.charAt(index))。equalsIgnoreCase(String.valueOf(b.charAt(index)))
更正:
Sachin Chauhan的答案确实是正确的,并且在运行时更好(即使用二进制搜索来搜索第一个差异)。
对于长度没有太大影响的情况(即相对较短的字符串),我将保留我的答案以允许使用更简单的解决方案程序员时间,但是更可取的是采用简单的解决方案。
这是原始答案:
因为这是一个简单的循环,所以我怀疑任何内置方法都不会在很大程度上改善“程序员”的时间(并且绝对不能提及很多运行时的改进)。
作为记录,我不知道有没有这样的Java方法(也许有一些外部库,但是您已经声明希望避免使用它们)。
我想,参考代码将遵循这些思路:
public int longestCommonPrefixLength(String s1, String s2) {
if (s1 == null || s1.length() == 0 || s2 == null || s2.length() == 0) {
return 0;
}
int commonPrefixLength = 0;
for (int i = 0; i < Math.min(s1.length(), s2.length()); i++) {
if (s1.charAt(i) == s2.charAt(i)) {
commonPrefixLength++;
} else {
break;
}
}
return commonPrefixLength;
}
正如我们所看到的那样,尽管Java具有所有的冗长性和我的“清晰”风格,但仍然只有18行代码。 :)
放宽一些清晰度,您甚至可以将for
缩短for
:
for (int i = 0; i < Math.min(s1.length(), s2.length()) && s1.charAt(i) == s2.charAt(i); i++, commonPrefixLength++);
少6行。
使其达到(正确)极限:
public int longestCommonPrefixLength2(String s1, String s2) {
if (s1 == null || s1.length() == 0 || s2 == null || s2.length() == 0) return 0;
int i = 0;
for (; i < Math.min(s1.length(), s2.length()) && s1.charAt(i) == s2.charAt(i); i++);
return i;
}
6 LOC :)
顺便说一句:
String
类具有boolean regionMatches(int toffset, String other, int ooffset, int len)
方法(在给定的len
内,在内部几乎可以完成上述工作)-您也可以迭代地增加len
直到它不再返回true为止,但这会当然,效率不可能接近任何地方。
使用流
String s1 = "Yellow";
String s2 = "Yelling";
int limit = (s1.length() > s2.length() ? s2.length() : s1.length()) - 1;
int ret = IntStream.range(0, limit)
.filter(i -> s1.charAt(i) != s2.charAt(i))
.findFirst().orElse(-1);
//-1 if the Strings are the same.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.