int contains(const char* word, const char* pattern) {
int pCount = 0, pLength = strlen(pattern);
char i;
while((i = *word++) != '\0') {
if (i == pattern[pCount]) {
if (++pCount == pLength) {
return 1;
}
}
}
return 0;
}
Refactorings
No refactoring yet !
soma
March 28, 2010, March 28, 2010 03:59, permalink
strstr() returns the location of the first occurrence of a substring within a string or NULL if not found.
#include <string.h> // strstr()
int contains(const char* word, const char* pattern) {
return strstr(word, pattern) ? 1 : 0;
}
soma
March 28, 2010, March 28, 2010 06:42, permalink
If you still want to write your own version (without using strstr() ) you need to change your algorithm a bit.
This is the best I could come up with. It's a bit uglier than I'd like but it works. It takes care of empty strings without having to test for special cases.
That is:
contains("", "") returns 1
contains("string", "") returns 1
contains("", "string") returns 0
I'm sure some C expert can improve and prettify this.
int contains(const char* word, const char* pattern) {
for(;;) {
const char* w = word++;
const char* p = pattern;
while (*w == *p && *p != '\0')
{ ++w; ++p; }
if (*p == '\0')
return 1;
if (*w == '\0')
return 0;
}
}
Ants
March 28, 2010, March 28, 2010 08:33, permalink
soma: Your implementation incorrectly return 0 for contains("psychosomatic", "soma").
Andreas: Let me recommend looking at:
http://en.wikipedia.org/wiki/Boyer%E2%80%93Moore_string_search_algorithm
http://en.wikipedia.org/wiki/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm
soma
March 28, 2010, March 28, 2010 16:37, permalink
@Ants: Can you show me exactly where my code is wrong? On my computer both solutions correctly return 1 for contains("psychosomatic", "soma").
Ants
March 29, 2010, March 29, 2010 05:36, permalink
@soma: Sorry, I goofed when I cut and pasted your code into my test harness. I accidentally stripped away the "for(;;)"
#define SOMAS_CODE_HANDLES_NULLS 1
int AntsCrypticContains(const char * word, const char * pattern)
{
const char * p = pattern;
while (word && *word && p && *p)
{
p = pattern;
for(const char * w = word++; *p && *p == *w; ++p, ++w)
;
}
return p && !*p;
}
int AntsReadableContains(const char * word, const char * pattern)
{
if (!word || !pattern)
return 0;
while (*word)
{
const char * w = word++;
const char * p = pattern;
while (*w++ == *p++)
{
if (!*p)
return 1;
}
}
return !*pattern;
}
int SomasContains(const char* word, const char* pattern) {
#ifdef SOMAS_CODE_HANDLES_NULLS
if (word == NULL || pattern == NULL)
return 0;
#endif
for(;;)
{
const char* w = word++;
const char* p = pattern;
while (*w == *p && *p != '\0')
{ ++w; ++p; }
if (*p == '\0')
return 1;
if (*w == '\0')
return 0;
}
}
void CallContains(const char *funcName,
int func(const char *, const char *),
const char *word,
const char *pattern)
{
printf("%s(\"%s\", \"%s\") returned %d\n", funcName, word, pattern, func(word, pattern));
}
typedef struct
{
const char * desc;
int (*func)(const char *, const char *);
} CONTAINSFUNCS;
CONTAINSFUNCS allContains[] =
{
{ "Ants' Cryptic Contains", AntsCrypticContains },
{ "Ants' Readable Contains", AntsReadableContains },
{ "Soma's Contains", SomasContains },
{ 0 }
};
void CallAllContains(const char *word, const char *pattern)
{
for (CONTAINSFUNCS *funcs = allContains; funcs->func; ++funcs)
CallContains(funcs->desc, funcs->func, word, pattern);
}
int main(int argc, char* argv[])
{
CallAllContains("", "");
CallAllContains("string", "");
CallAllContains("", "string");
CallAllContains("psychosomatic", "soma");
CallAllContains("soma", "soma");
CallAllContains("abc", "xyz");
#ifdef SOMAS_CODE_HANDLES_NULLS
CallAllContains(NULL, NULL);
CallAllContains("a", NULL);
CallAllContains(NULL, "a");
#endif // SOMAS_CODE_HANDLES_NULLS
return 0;
}
soma
March 29, 2010, March 29, 2010 20:46, permalink
Ants: you're right: I chose not to handle NULL pointers, following the pattern of strcpy(), strstr(), etc. It seems more c-like to me.
Loradae
November 24, 2011, November 24, 2011 16:07, permalink
If I were a Teenage Mutant Ninja Turtle, now I'd say Kowbangua, dude!
ERROR_BAD_DUPLICATES
Loradae
November 24, 2011, November 24, 2011 16:07, permalink
If I were a Teenage Mutant Ninja Turtle, now I'd say Kowbangua, dude!
ERROR_BAD_DUPLICATES
Loradae
November 24, 2011, November 24, 2011 16:07, permalink
If I were a Teenage Mutant Ninja Turtle, now I'd say Kowbangua, dude!
ERROR_BAD_DUPLICATES
Unity
November 26, 2011, November 26, 2011 17:08, permalink
Brilliance for free; your parents must be a sweetehart and a certified genius.
ERROR_BAD_DUPLICATES
I wrote the following function in C to return a 1 if the pattern is contained in the word, or a 0 otherwise.
Is this the correct way to write such a function?