查找string是否包含没有Java.substring的子字符串

时间:2017-04-27 07:50:53

标签: java string algorithm

  

设计一个函数hasCheated(String s1,String s2,int N),如果两个字符串s1, s2具有至少长度为N的公共子字符串,则返回true。不使用.contains,.substring

是否需要转换为char数组或类似的方法?

我正在考虑找到最长的公共子字符串,然后再次查看它N。这有什么办法?

2 个答案:

答案 0 :(得分:2)

首先找到最长的公共子串比检查是否存在至少给定大小的匹配要慢。你可以在获得比赛后立即停止,即使可能有更长的比赛。

我会构建一个哈希集(或者如果需求更复杂的哈希映射),它表示长度为N的所有子字符串(没有实际创建那些子字符串)并使用它来扫描长度为N的字符串匹配。

您可以在O(M)时间内执行此操作,其中M是最长字符串的长度。

您可以像这样创建一个子字符串类。

class Substring {
    final String s;
    final int offset, length, hashCode;

    Substring(String s, int offset, int length) {
        this.s = s;
        this.offset = offset;
        this.length = length;
        this.hashCode = hashCode(s, offset, length); // define to taste
    }

    public int hashCode() { return hashCode; }

    public boolean equals(Object o) {
       if (!(o instanceof Substring)) return false;
       Substring ss = (Substring) s;
       if (hashCode != ss.hashCode || length != ss.length) return false;
       for (int i = 0; i < length; i++) 
           if (s.charAt(i) != ss.s.charAt(i))
               return false;
       return true;
    }
}

要构建HashSet,您可以在O(n)中执行以下操作,其中n是s1.length()

Set<Substring> substrings = new HashSet<>();
for (int i = 0; i < s1.length() - n; i++) {
    Substring ss = new Substring(s1, i, n);
    substrings.add(ss);
}

要搜索匹配项,您可以在O(n)中执行以下操作,其中n是s2.length()

for (int i = 0; i < s2.length() - n; i++) {
    Substring ss = new Substring(s2, i, n);
    if (substrings.contains(ss))
         return true; // found a match.
}

答案 1 :(得分:1)

所以,没有containssubstring我假设你不打算使用任何Java API。这是一个使用动态编程的实现:

public static boolean hashCheated(String a, String b, int N) {
    int m = a.length();
    int n = b.length();

    int max = 0;

    int[][] dp = new int[m][n];

    for(int i=0; i<m; i++){
        for(int j=0; j<n; j++){
            if(a.charAt(i) == b.charAt(j)){
                if(i==0 || j==0){
                    dp[i][j]=1;
                }else{
                    dp[i][j] = dp[i-1][j-1]+1;
                }

                if(max < dp[i][j])
                    max = dp[i][j];
            }

        }
    }

    return (max >= N);
}