去除重复字母问题和字符匹配问题

212 阅读2分钟

去除重复字母问题

char * wipeOffRepetition(char *s){
    //得到字符串长度
    int size = (int)strlen(s);
    //字符串为空
    if (s == NULL || size == 0) {
        return "";
    }else if (size == 1){
        //字符串长度为1
        return s;
    }else{
        //初始化一个栈
        //栈顶指针
        int top = -1;
        char *result = (char *)malloc(sizeof(char)*(size+1));
        //存储26个字母出现的次数,并清空数组
        int count[26] = {0};
        //得到每个字母出现的次数
        for (int i=0; i<size; i++) {
            count[s[i]-'a']++;
        }
        //去重
        for (int i=0; i<size; i++) {
            //判断当前字符在result中是否存在
            int have = 0;
            for (int j=0; j<= top; j++) {
                if (s[i] == result[j]) {
                    have = 1;
                    //存在,跳出循环
                    break;
                }
            }
            if (have == 0) {
                //当前字符在result中不存在
                /**
                 1.栈不为空;
                 2.栈顶字符大于当前字符;
                 3.栈顶字符在后面还会出现
                 */
                while (top != -1 && result[top] > s[i] && count[result[top] -'a'] > 1) {
                    //栈顶字符大于当前字符,并且后面还会出现
                    //则栈顶字符出栈
                    top--;
                    count[s[i]-'a']--;
                }
                //将当前字符入栈
                top++;
                result[top] = s[i];
            }else{
                //当前字符在result中存在,出现的次数-1
                count[s[i]-'a']--;
            }
        }
        //字符结尾都有个\0
        result[++top] = '\0';
        
        return result;
    }
}

BF算法

int match(char *s1,char *s2){
    //记录s2在s1中首次出现的位置
    int index = -1;
    //获取s1,s2的长度
    int s1Size = (int)strlen(s1);
    int s2Size = (int)strlen(s2);
    //如果s2比s1长,直接返回-1
    if (s1Size < s2Size) {
        return index;
    }
    //BF暴力判断
    for (int i=0; i<= s1Size-s2Size; i++) {
        //将与s2等长的s1的当前子串与s2进行比较
        //例如
        //abcedef
        //abc
        ///bce
        ////ced
        /////ede
        //////def
        //与ced比较
        for (int j=0; j<s2Size; j++) {
            if (s1[i+j] == s2[j]) {
                //直到比较完后,记录当前位置
                if (j == s2Size-1) {
                    index = i;
                }
            }else{
        //如果s1的当前子串其中的一个字符与s2中的对应字符不相同,则结束比较
                break;
            }
        }
        if (index != -1) {
            //判断到一个结果后直接跳出循环
            break;
        }
    }

    return index;
}

RK算法

int RK(char *s1,char *s2){
    //得到字符长度
    int s1Len = (int)strlen(s1);
    int s2Len = (int)strlen(s2);
    //
    unsigned int s1Hash = 0;
    unsigned int s2Hash = 0;
    //
    int D = 26;
    
    //求最高阶的值
    int hValue = 1;
    
    for (int i=0; i!= s2Len; i++) {
        s1Hash = (D * s1Hash) + s1[i] - 'a';
        s2Hash = (D * s2Hash) + s2[i] - 'a';
        
        if (i<s2Len-1) {
            hValue = hValue *D;
        }
    }
    
    
    
    int index = -1;
    for (int i=0; i<= s1Len-s2Len; i++) {
        if (s1Hash == s2Hash) {
            for (int j=0; j<s2Len; j++) {
                if (s1[i+j] == s2[j]) {
                    if (j == s2Len-1) {
                        index = i;
                    }
                }else{
                    break;
                }
            }
        }
        if (index != -1) {
            break;
        }
        
        s1Hash = (s1Hash -hValue*(s1[i]-'a')) * D + s1[i+s2Len] - 'a';
    }
    return index;
}