我试图找到c中两个字符串匹配的时间,如果我们有两个或更多个星,多个字符串组合可能是合适的。例如"abcdb"
& "*b*"
匹配两次。我当前的代码有效,但它返回四个。我不知道我在这里缺少什么。
#include <stdio.h>
int nmatch(char *s1, char *s2) {
if (*s1 != '\0' && *s2 != '\0' && *s2 == '*' && (*s2 + 1) != *s1) {
return nmatch(s1 + 1, s2) + 1;
}
if (*s1 == *s2) {
return nmatch(s1 + 1, s2 + 1);
}
if (*s1 == *s2 && *s1 == '\0' && *s2 == '\0') {
return 0;
}
return (1);
}
int main() {
char ap[] = "abcd";
char ab[] = "*b*";
printf("%d", nmatch(ap, ab));
return 0;
}
答案 0 :(得分:1)
您的代码不计算s1
匹配模式s2
的不同方式的数量。对于相同的字符串,它甚至不返回1.
第一次比较(*s2 + 1) != *s1
不正确,您可能认为*(s2 + 1) != *s1
等同于s2[1] != *s1
,但此修复程序不足以纠正算法。
以下是一个天真的实现:
int nmatch(const char *s1, const char *s2) {
int count;
while (*s2 != '\0' && *s2 != '*' && *s1 == *s2) {
s1++;
s2++;
}
if (*s2 == '\0')
return *s1 == '\0';
if (*s2 != '*')
return 0;
while (*s2 == '*') /* skip all stars */
s2++;
if (*s2 == '\0')
return 1;
for (count = 0;; s1++) {
count += nmatch(s1, s2);
if (*s1 == '\0')
break;
}
return count;
}
答案 1 :(得分:0)
我认为你的算法错了。再加上有缺陷的实施,这将无处可去。
有输入字符串和模式字符串。如果模式的第一个字符不 a *
并且不等于输入字符串的第一个字符,则返回0(这是不匹配)。
如果它们相等,则删除输入和模式的第一个字符,并返回缩小的输入和模式的匹配数。
另一方面,如果模式的第一个字符是*
,那么(在一个循环中)将剩余模式与完整输入字符串的匹配数相加,输入字符串没有第一个,然后没有第二个字符......依此类推,直到输入字符串为空。
如果输入和模式都为空:返回1.如果只有一个字符串为空:返回0。
我将它实现为直接递归函数(用于生产用途,应该转换为迭代版本):
unsigned matches(char const * const input, char const * const pattern) {
if (! *pattern) {
// An empty pattern matches only the empty
// string, nothing else
return (*input) ? 0 : 1;
}
if (*pattern == '*') {
// a wildcard could be zero to any number
// of characters. Sum the number of matches
// for each possibility (excluding the empty
// rest of input for now)
char const * rest = input;
unsigned count = 0;
while (*rest) {
count += matches(rest, pattern + 1);
++rest;
}
// Add matches for the empty rest of input
count += matches(rest, pattern + 1);
return count;
}
if (! *input) {
// A non empty, non wildcard pattern cannot
// match the empty string
return 0;
}
if (*pattern == *input) {
// non wildcard match, count the ways the rest of
// the pattern matches the rest of the input.
return matches(input + 1, pattern + 1);
}
else {
// mismatch!
return 0;
}
}
为了处理模式中存在多个相邻通配符时可能匹配的组合爆炸,可以先从模式中删除这些通配符。