通配符匹配算法
要求:1,a?b,查找以a开始,b结尾中间为任意字符的子串出现的次数
2.?和的位置可以在前,后或者中间可以有任意多个,可以相互组合
3.起始位置不同的匹配视为两次不同的匹配,例如,a?b aabbacbc 结果为3,aa aaa结果为2
4.起始位置相同的匹配,视为一次匹配,例如 ab 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;
}