Match sub-string within a string with tolerance of 1 character mismatch

前端 未结 5 1661
天命终不由人
天命终不由人 2020-12-28 11:07

I was going through some Amazon interview questions on CareerCup.com, and I came across this interesting question which I haven\'t been able to figure out how to do. I have

5条回答
  •  臣服心动
    2020-12-28 11:27

    With arbitary no. of tolerance levels.

    Worked for all the test cases I could think of. Loosely based on |/|ad's solution.

    #include
    #include
    
    report (int x, char* str, char* sstr, int[] t) {
        if ( x )
            printf( "%s is a substring of %s for a tolerance[%d]\n",sstr,str[i],t[i] );
        else
            printf ( "%s is NOT a substring of %s for a tolerance[%d]\n",sstr,str[i],t[i] );
    }
    
    int find_with_tolerance (char *str, char *sstr, int tol) {
    
        if ( (*sstr) == '\0' ) //end of substring, and match
            return 1;
    
        if ( (*str) == '\0' ) //end of string
            if ( tol >= strlen(sstr) ) //but tol saves the day
                return 1;
            else    //there's nothing even the poor tol can do
                return 0;
    
        if ( *sstr == *str ) { //current char match, smooth
            return find_with_tolerance ( str+1, sstr+1, tol );
        } else {
            if ( tol <= 0 ) //that's it. no more patience
                return 0;
            for(int i=1; i<=tol; i++) {
                if ( *(str+i) == *sstr ) //insertioan of a foreign character
                    return find_with_tolerance ( str+i+1, sstr+1, tol-i );
                if ( *str == *(sstr+i) ) //deal with dletion
                    return find_with_tolerance ( str+1, sstr+i+1, tol-i );
                if ( *(str+i) == *(sstr+i)  ) //deal with riplacement
                    return find_with_tolerance ( str+i+1, sstr+i+1, tol-i );
                if ( *(sstr+i) == '\0' ) //substr ends, thanks to tol & this loop
                    return 1;
            }
            return 0; //when all fails
        }
    }
    
    int find (char *str, char *sstr, int tol ) {
        int w = 0;
        while (*str!='\0')
            w |= find_with_tolerance ( str++, sstr, tol );
        return (w) ? 1 : 0;
    }
    
    int main() {
        const int n=3; //no of test cases
        char *sstr = "dog"; //the substr
        char *str[n] = { "doox", //those cases
                        "xxxxxd",
                        "xxdogxx" };
        int t[] = {1,1,0}; //tolerance levels for those cases
        for(int i = 0; i < n; i++) {
            report( find ( *(str+i), sstr, t[i] ), *(str+i), sstr, t[i] );
        }
        return 0;
    }
    

提交回复
热议问题