通配符匹配算法

通配符匹配算法

要求:1,a?b,查找以a开始,b结尾中间为任意字符的子串出现的次数
2.?和的位置可以在前,后或者中间可以有任意多个,可以相互组合
3.起始位置不同的匹配视为两次不同的匹配,例如,a?b aabbacbc 结果为3,aa aaa结果为2
4.起始位置相同的匹配,视为一次匹配,例如 a
b abbAcbc 结果为1
5.?表示任意单个字符,任意位置可以是多个也可以全是;*表示任意长度字符(可以为0),可以出现在任意位置,可以有多个,但不可以全是
例如,?? abcdabcabd 9
比如 a?b aabbacbc,匹配的子串有 1.aab 2.aabb 3.abb 4.acb,1和2起始位置相同,视为一个
aab aabb aabbacb是一个起点


#include <string.h>
#include <stdio.h>
#include <stdlib.h>

int stringmatchlen(const char *pattern, int patternLen,
    const char *string, int stringLen, int nocase)
{
    if(strcmp(pattern,string) == 0)
    {
        return 1;
    }

    while (patternLen) {
        switch (pattern[0]) {
        case '*':
            while (pattern[1] == '*') {
                pattern++;
                patternLen--;
            }
            if (patternLen == 1)
                return 1; /** match */
            while (stringLen) {
                if (stringmatchlen(pattern + 1, patternLen - 1,
                    string, stringLen, nocase))
                    return 1; /** match */
                string++;
                stringLen--;
            }
            return 0; /** no match */
            break;
        case '?':
            if (stringLen == 0)
                return 0; /** no match */
            string++;
            stringLen--;
            break;
        //case '[':
        //{
        //    int inot, match;

        //    pattern++;
        //    patternLen--;
        //    inot = pattern[0] == '^';
        //    if (inot) {
        //        pattern++;
        //        patternLen--;
        //    }
        //    match = 0;
        //    while (1) {
        //        if (pattern[0] == '\\') {
        //            pattern++;
        //            patternLen--;
        //            if (pattern[0] == string[0])
        //                match = 1;
        //        }
        //        else if (pattern[0] == ']') {
        //            break;
        //        }
        //        else if (patternLen == 0) {
        //            pattern--;
        //            patternLen++;
        //            break;
        //        }
        //        else if (pattern[1] == '-' && patternLen >= 3) {
        //            int start = pattern[0];
        //            int end = pattern[2];
        //            int c = string[0];
        //            if (start > end) {
        //                int t = start;
        //                start = end;
        //                end = t;
        //            }
        //            if (nocase) {
        //                start = tolower(start);
        //                end = tolower(end);
        //                c = tolower(c);
        //            }
        //            pattern += 2;
        //            patternLen -= 2;
        //            if (c >= start && c <= end)
        //                match = 1;
        //        }
        //        else {
        //            if (!nocase) {
        //                if (pattern[0] == string[0])
        //                    match = 1;
        //            }
        //            else {
        //                if (tolower((int)pattern[0]) == tolower((int)string[0]))
        //                    match = 1;
        //            }
        //        }
        //        pattern++;
        //        patternLen--;
        //    }
        //    if (inot)
        //        match = !match;
        //    if (!match)
        //        return 0; /** no match */
        //    string++;
        //    stringLen--;
        //    break;
        //}
        //case '\\':
        //    if (patternLen >= 2) {
        //        pattern++;
        //        patternLen--;
        //    }
            /** fall through */
        default:
            if (!nocase) {
                if (pattern[0] != string[0])
                    return 0; /** no match */
            }
            else {
                if ((int)pattern[0] != (int)string[0])
                    return 0; /** no match */
            }
            string++;
            stringLen--;
            break;
        }
        pattern++;
        patternLen--;
        if (stringLen == 0) {
            while (*pattern == '*') {
                pattern++;
                patternLen--;
            }
            break;
        }
    }
    if (patternLen == 0 && stringLen == 0)
        return 1;
    return 0;
}

int stringmatch(const char *pattern, const char *string, int nocase) {
    return stringmatchlen(pattern, strlen(pattern), string, strlen(string), nocase);
}

const char* substring(const char* ch, int pos, int length)
{
    //定义字符指针 指向传递进来的ch地址
    int len = strlen(ch);
    char* pch = (char*)calloc(sizeof(char), len + 1);
    memset(pch, 0, len + 1);
    // ReSharper disable once CppDeprecatedEntity
    strcpy_s(pch,len+1, ch);
    
    //通过calloc来分配一个length长度的字符数组,返回的是字符指针。
    char* subch = (char*)calloc(sizeof(char), length + 1);
    int i;
    //只有在C99下for循环中才可以声明变量,这里写在外面,提高兼容性。  
    pch = pch + pos;
    //是pch指针指向pos位置。  
    for (i = 0; i < length; i++)
    {
        subch[i] = *(pch++);
        //循环遍历赋值数组。  
    }
    //free(pch);
    subch[length] = '\0';//加上字符串结束符。  
    return subch;       //返回分配的字符数组地址。  
}

int getmatchcount(const char*pattern, const char *string)
{
    int len = strlen(string);
    int count = 0;
    int itmp = 0;
    for (int i = 0; i < len; i++)
    {
        itmp = 0;
        for (int j =i;j<len;j++)
        {
            const char *tmp = substring(string, i, ++itmp);
            if (stringmatch(pattern, tmp, 1))
            {
                count++;
                break;
            }
        }
        
        
    }
    return count;
}

int main(int argc, const char *argv[])
{
    char s1[100], s2[100];
    while (1) {
        /*if (stringmatch(s1, s2, true)) {
            std::cout << "yes" << std::endl;
        }
        else {
            std::cout << "no" << std::endl;
        }*/
        scanf_s("%s", s1,100);
        scanf_s("%s", s2,100);
        printf("%d\n", getmatchcount(s1, s2));
    }

    return 0;
}

参考文档:
(http://www.cnblogs.com/UnGeek/p/3376652.html)

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值