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

时间:2017-01-30 16:19:04

标签: java string pattern-matching

因此,对于我面临的问题,我想知道一个序列(从索引0开始)两个字符串的长度是多少相同的' - 我认为举一个例子会更清楚;

  • 我希望方法返回4,如果两个字符串是"黄石"和#34;大喊" - 意思是,两个字符串的前4个字符匹配(" Yell")

还有更多(时间)有效的方法来解决这个问题,而不仅仅是迭代这两个词吗?我可以使用某种内置方法吗? (对于我的任务,我想避免导入任何自定义库)

4 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:1)

你不必遍历这两个文本。迭代较小的一个并比较相同索引处的字符。当你发现不匹配时就会中断

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 ifu希望它不区分大小写。 将String.valueOf(a.charAt(索引))。equalsIgnoreCase(将String.valueOf(b.charAt(索引)))

答案 2 :(得分:1)

<强>校正:

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的所有冗长和我的清晰度&#34;风格,它仍然只有18行代码。 :)

放宽一些清晰度,您甚至可以将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,直到它不再返回是的,当然,这不会是几乎相同的效率。

答案 3 :(得分:1)

使用Streams

    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.