繁体   English   中英

两个字符串的字符串匹配的前n个字母

[英]String-matching first n letters of two strings

所以对于一个我面临的问题,我想知道一个序列(从索引0开始)两个字符串“相同”有多长时间-我想举一个例子会更清楚。

  • 如果两个字符串分别为“ Yellowstone”和“ Yelling”,则我希望该方法返回4-这意味着两个字符串的前4个字符匹配(“ Yell”)

除了仅迭代两个单词之外,还有其他(省时)高效的方法吗? 我可以利用某种内置方法吗? (对于我的任务,我想避免导入任何自定义库)

我认为最快的方法是使用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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM