簡體   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