比较字符串与通配符

时间:2014-05-04 14:20:33

标签: c arrays string

在C中,我怎样才能将包含*(可以是任意字符组合)的字符串与二维字符串矩阵进行比较?

例如,我有go*s这个词。它可以生成单词"华丽" (*是" orgeou"),"善良","山羊","去"我应该阅读整本字典中的单词,并将它们与包含一个或多个星号(*)的单词进行比较。必须打印可以从带星号的单词生成的每个单词。如果这两个单词的长度相同,那么很容易比较,因为*只能是一个字母。

int fq(char *s1, char *s2){
int i, a=0, b=0, s=0;
while (1){
    if (s1[a]=='\0')
        break;
    a++;
}
if (strlen(s1)==strlen(s2)){
    for(i=0; i<a; i++){
        if (s1[i]=='*'){
            b++;
            }
        if (s1[i]==s2[i]){
            b++;
            }
        }
    }
if (b==a)
    return 1;

5 个答案:

答案 0 :(得分:3)

通过逐字符检查模式字符串并应用以下规则,您可以非常轻松地编写一个递归函数,用于将sting与另一个字符串与其中的通配符进行比较:

  • 如果模式[p] ==&#39; \ 0&#39;:如果候选人[c] ==&#39; \ 0&#39;
  • ,则模式匹配
  • 如果模式[p] ==&#39; *&#39;:尝试将候选人[c] ...候选人[c + n]与模式[p + 1]匹配
  • 如果模式[p]!=&#39;?&#39;和模式[p]!=候选人[c]:不匹配
  • 否则,将模式[p + 1]与候选[c + 1]
  • 匹配

这些规则很容易编写为匹配的递归函数:

#include <stdbool.h>

bool match(const char *pattern, const char *candidate, int p, int c) {
  if (pattern[p] == '\0') {
    return candidate[c] == '\0';
  } else if (pattern[p] == '*') {
    for (; candidate[c] != '\0'; c++) {
      if (match(pattern, candidate, p+1, c))
        return true;
    }
    return match(pattern, candidate, p+1, c);
  } else if (pattern[p] != '?' && pattern[p] != candidate[c]) {
    return false;
  }  else {
    return match(pattern, candidate, p+1, c+1);
  }
}

然后,你可以这样做:

match("f*o", "foo", 0, 0);

这不是一种有效的方法,但我认为它很容易理解和实施。如果您需要更高效的内容,可以从以下内容开始:http://en.wikipedia.org/wiki/String_searching_algorithm

答案 1 :(得分:0)

以下内容适用于包含单个*的输入字符串。

  1. 在输入单词的开头一次开始比较一个字符。
  2. 如果遇到*,请向后比较 last 字符中的两个字符串。
  3. 如果您不匹配,请返回0
  4. 如果您遇到*,您就完成了。
  5. 如果不匹配,请返回0
  6. (添加:此算法也可以在第一个或最后一个位置使用*。)

答案 2 :(得分:0)

你可以检查前两个字符是否是&#34; go&#34;如果最后一个是&#39;。

以最简单的方式做到这一点,我看到的是一个简单的条件:

if (strncmp(str, "go", 2) == 0 && str[strlen(str) - 1] == 's')

如果字符串匹配,strncmp返回0。

您还应该确保字符串长度至少为2个字符,否则您在分析字符串的2个字符时会出现分段错误,您可以在上述条件中添加:

strlen(str) >= 2

答案 3 :(得分:0)

前段时间有同样的问题,并提出了这个问题。在不使用递归函数的情况下对主字符串进行单次传递以提高效率。如果您偶然发现了该线程,希望对您有所帮助。

var uids = sent.Search (SearchQuery.HeaderContains ("Message-ID", message.MessageId));
if (uids.Count == 1) {
    // looks like the message was added
}

答案 4 :(得分:0)

我喜欢 Robert James Mieta 在他的单遍回答中的方法,只是通配符逻辑对我来说不太适用。我已经调整了他的解决方案如下。它可能也不完美,可能有一些不可预见的边缘情况,但可以满足我目前的需求:

int is_match(char* line, char* pattern)
{
  int wildcard = 0;

  do
  {
    if ((*pattern == *line) || (*pattern == '?'))
    {
      line++;
      pattern++;
    }
    else if (*pattern == '*')
    {
      if (*(++pattern) == '\0')
      {
        return 1;
      }
      wildcard = 1;
    }
    else if (wildcard)
    {
      if (*line == *pattern)
      {
        wildcard = 0;
        line++;
        pattern++;
      }
      else
      {
        line++;
      }
    } 
    else
    {
      return 0;
    }
  } while (*line);

  if (*pattern == '\0')
  {
    return 1;
  }
  else
  {
    return 0;
  }
}