首页 > 试题广场 >

字符串通配符

[编程题]字符串通配符
  • 热度指数:173934 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解

问题描述:在计算机中,通配符一种特殊语法,广泛应用于文件搜索、数据库、正则表达式等领域。现要求各位实现字符串通配符的算法。
要求:
实现如下2个通配符:
*:匹配0个或以上的字符(注:能被*和?匹配的字符仅由英文字母和数字0到9组成,下同)
?:匹配1个字符

注意:匹配时不区分大小写。

输入:
通配符表达式;
一组字符串。

输出:

返回不区分大小写的匹配结果,匹配成功输出true,匹配失败输出false
数据范围:字符串长度:
进阶:时间复杂度:,空间复杂度:

输入描述:

先输入一个带有通配符的字符串,再输入一个需要匹配的字符串



输出描述:

返回不区分大小写的匹配结果,匹配成功输出true,匹配失败输出false

示例1

输入

te?t*.*
txt12.xls

输出

false
示例2

输入

z
zz

输出

false
示例3

输入

pq
pppq

输出

false
示例4

输入

**Z
0QZz

输出

true
示例5

输入

?*Bc*?
abcd

输出

true
示例6

输入

h*?*a
h#a

输出

false

说明

根据题目描述可知能被*和?匹配的字符仅由英文字母和数字0到9组成,所以?不能匹配#,故输出false      
示例7

输入

p*p*qp**pq*p**p***ppq
pppppppqppqqppqppppqqqppqppqpqqqppqpqpppqpppqpqqqpqqp

输出

false
//6ms递归

#include <ctype.h>
#include <stdio.h>

int ans(char *a, int lenA, int i, char *b, int lenB, int j) {
    if (!(i < lenA) && j < lenB) return 0;
    if (!(i < lenA) && !(j < lenB)) return 1;
    if (a[i] == '?') {
        return isalnum(b[j]) && ans(a, lenA, i+1, b, lenB, j+1);
    } else if (a[i] == '*') {
        while(a[i+1] == '*') {
            i++;
        }
        if (a[i+1] == '\0') {
            return 1;
        }
        for (int k = j; k < lenB; ++k) {
            if (ans(a, lenA, i+1, b, lenB, k)) {
                return 1;
            }
        }
        return 0;
    } else {
        return tolower(a[i]) == tolower(b[j]) && ans(a, lenA, i+1, b, lenB, j+1);
    }
}

int main() {
    char a[101];
    char b[101];
    scanf("%s", a);
    scanf("%s", b);
    if (ans(a, strlen(a), 0, b, strlen(b), 0)) {
        printf("true");
    } else {
        printf("false");
    }
    return 0;
}
发表于 2024-09-22 21:37:11 回复(0)
//确实是很多时候就是递归想不明白,还是需要借鉴一下递归

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

int cmp_str(char *std, char *str)
{
  int i = 0, j = 0;

  while (i < strlen(std) && j < strlen(str))
  {
    if (std[i] == '?')
    {
      if (isdigit(str[j])||isalpha(str[j]))
        j++, i++;
      else
        return 0;
    }
    else if (std[i] == str[j])
      i++, j++;
    else if (std[i] == '*')
    {
      while (std[i + 1] == '*')
        i++;
      //三种情况 匹配0个字符 匹配下一个字符,匹配多个(std不动,还是*在匹配,str下移)
      return cmp_str(std + i + 1, str + j) || cmp_str(std + i + 1, str + j + 1) || cmp_str(std + i, str + j + 1);
    }
    else
      return 0;
  }

  if (i == strlen(std) && j == strlen(str))
    return 1;
  else
    return 0;
}

int main()
{
  char std[200];
  char str[200];
  while (scanf("%s %s",std,str) != EOF)
  {
    for (int k = 0; k < strlen(str); k++)
    {
        str[k] = tolower(str[k]);
    }
    for (int k = 0; k < strlen(std); k++)
    {
        std[k] = tolower(std[k]);
    }
    //全部替换成小写

    if (cmp_str(std, str) == 1)
    {
      printf("true\n");
    }
    else
      printf("false\n");
  }

  return 0;
}
发表于 2023-10-23 16:50:57 回复(0)
#include <ctype.h>
#include <stdbool.h>
#include <stdio.h>

bool isCor(char c)
{
    if (isdigit(c) || islower(c)) {
        return true;
    }

    return false;
}

bool match(char *s1, char *s2)
{
    int i = 0; 
    int j = 0;
    int i_pre = 0;
    int j_pre = 0;
    int flag = 0;

    while (s2[j] != '\0') {
        s1[i] = tolower(s1[i]);
        s2[j] = tolower(s2[j]);
        if (s1[i] == '*' && isCor(s2[i])) {
            i_pre = i;
            j_pre = j;
            flag = 1;
            i++;
        } else if (s1[i] == '*') {
            i++;
        } else if (flag) {
            i = i_pre;
            j = j_pre + 1;
            flag = 0;
        } else {
            return false;
        }
    }

    while (s1[i] != '\0') {
        if (s1[i] != '*') {
            return false;
        }
        i++;
    }

    return true;
}
int main() {
    char str1[100] = {0};
    char str2[100] = {0};

    gets(str1);
    gets(str2);

    char *ret = match(str1, str2) ? "true" : "false";
    printf("%s\n", ret);
    return 0;
}

发表于 2023-08-31 10:59:29 回复(1)
为什么这个用例匹配结果是false啊,求大神指点
te?t*123
text1234
发表于 2023-04-16 18:51:37 回复(2)
#include <stdio.h>
#include <string.h>
#define    N    100
int main()
{
    char s[N],p[N];
    int dp[N][N]={1},i,lenp,lens,j,k,flag;
    scanf("%s%s",p,s);
    lenp=strlen(p);
    lens=strlen(s);
    for(i=0;i<lenp;i++)
        if(p[i]>='A'&&p[i]<='Z')
            p[i]+='a'-'A';
    for(i=0;i<lens;i++)
        if(s[i]>='A'&&s[i]<='Z')
            s[i]+='a'-'A';
    for(i=0;i<lenp;i++)
    {
        for(j=0;j<lens;j++)
        {
            if(dp[i][j])
            {
                if(p[i]==s[j])
                {
                    dp[i+1][j+1]=1;
                }
                else if(p[i]=='*')
                {
                    dp[i+1][j]=1;
                    k=j;
                    while((s[k]>='0'&&s[k]<='9')||(s[k]>='a'&&s[k]<='z'))
                    {
                        dp[i+1][k+1]=1;
                        k++;
                    }
                }
                else if(p[i]=='?'&&((s[j]>='0'&&s[j]<='9')||(s[j]>='a'&&s[j]<='z')))
                {
                    dp[i+1][j+1]=1;
                }
            }
        }
    }
    if(dp[lenp][lens])
        printf("true");
    else
        printf("false");
    return 0;
}
疯狂打补丁。。。
发表于 2022-05-04 08:58:05 回复(0)
#include<stdio.h>
#include<string.h>

int max(int a, int b)
{
    return a>b?a:b;
}
int match(char a[] ,char b[])
{
    int lena = strlen(a);
    int lenb = strlen(b);
    int dp[100][100] = {0};
    dp[0][0] = 1;
    for(int j = 0;j < lenb;j++)
    {
        if((b[j] == '.') || ((b[j] >= '0') && (b[j] <= '9')) || ((b[j] >= 'a') && (b[j] <= 'z')) || ((b[j] >= 'A') && (b[j] <= 'Z')))
        {
            continue;
        }
        else
        {
            return 0;
        }
    }
    for(int i = 1;i <= lena;i++)
    {
        if(a[i - 1] == '*')
        {
            dp[i][0] = 1;
        }
        else
        {
            break;
        }
    }
    for(int i = 1;i <= lena;i++)
    {
        for(int j = 1;j <= lenb;j++)
        {
            if(a[i - 1] == '?')
            {
                dp[i][j] = max(dp[i][j] , dp[i-1][j-1]);
            }
            if((a[i - 1] == b[j - 1]) || (a[i - 1] == b[j - 1] + 32) || (a[i - 1] == b[j - 1] - 32))
            {
                dp[i][j] = max(dp[i][j] , dp[i-1][j-1]);
            }
            if(a[i - 1] == '*')
            {
                dp[i][j] = max(dp[i][j] , (dp[i-1][j] || dp[i][j - 1]));
            }
        }
    }
    return dp[lena][lenb];
    
}

int main()
{
    int m;
    char a[100],b[100];
    while(scanf("%s",&a) != EOF)
    {
        scanf("%s",&b) ;
        m = match(a, b);
         if(m == 1)
    {
        printf("true\n");
    }
    else{
        printf("false\n");
    }
    }
}

发表于 2021-08-24 01:29:51 回复(0)

没全对,差一点点

#include<stdio.h>
int isChar(char C) {
    if((C >= 'A' && C <= 'Z') || (C >= '0' && C <= '9') || C == '.') {
        return 1;
    } else {
        return 0;
    }
}

char changeUp(char C) {
    if(C >= 'a' && C <= 'z') {
        C -= 32;
    }
    return C;
}
int getDP(char a[500], char b[500]) {
    int m = strlen(a);
    int n = strlen(b);
    int dp[500][500] = {0}, maxlen = 0;
    for(int i = 0; i < m; i++) {
        for(int j = 0; j < n; j++) {
            char p = changeUp(a[i]);
            char q = changeUp(b[j]);
            if((p == q) || 
               ((p == '?' || p == '*') && isChar(q) == 1 )) {
                dp[i][j] = dp[i-1][j-1] + 1;
                if(dp[i][j] > maxlen) {
                    maxlen = dp[i][j];
//                     break;
//                     i--;
                }
            }
        }
    }
    return maxlen;
}
int main() {
    char a[500], b[500];
    while(gets(a) && gets(b)) {
        if(strstr(a, "*") == NULL && strstr(a, "?") == NULL) {
            if(strlen(a) == strlen(b)) {
                int result = 1;
                for(int i = 0; i < strlen(a); i++) {
                    if(a[i] != b[i]){
                        result = 0;;
                    }
                }
                if(result == 1) {
                    printf("true\n");
                } else {
                    printf("false\n");
                }
            } else {
                printf("false\n");
            }
            continue;
        }
        char sub[500] = {0};
        char *p = &a;
        char *q = p;
        while(*p != '\0') {
            if(*p != '*' && *p != '?') {
                q = p;
                break;
            }
            p++;
        }
        if(*p == '\0') {
            printf("true\n"); // 通配符字符串只包含*?,直接表示true
            continue;
        }
        int maxlen = 0;
        maxlen = getDP(a, b);
        int smallLen = strlen(a) < strlen(b) ? strlen(a): strlen(b);
//        printf("%d ", maxlen);
//        printf("%d\n", smallLen);
        if(maxlen >= smallLen) {
            printf("true\n");
        } else {
            printf("false\n");
        }

    }
}
发表于 2021-08-21 21:46:02 回复(0)