C398dd0c2ca7d5281d0a83242a924e76

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?

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 !

D41d8cd98f00b204e9800998ecf8427e

soma

March 28, 2010, March 28, 2010 03:59, permalink

2 ratings. Login to rate!

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;
}
D41d8cd98f00b204e9800998ecf8427e

soma

March 28, 2010, March 28, 2010 06:42, permalink

2 ratings. Login to rate!

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;
	}
}
F9a9ba6663645458aa8630157ed5e71e

Ants

March 28, 2010, March 28, 2010 08:33, permalink

No rating. Login to rate!

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

D41d8cd98f00b204e9800998ecf8427e

soma

March 28, 2010, March 28, 2010 16:37, permalink

No rating. Login to rate!

@Ants: Can you show me exactly where my code is wrong? On my computer both solutions correctly return 1 for contains("psychosomatic", "soma").

F9a9ba6663645458aa8630157ed5e71e

Ants

March 29, 2010, March 29, 2010 05:36, permalink

No rating. Login to rate!

@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;
}
D41d8cd98f00b204e9800998ecf8427e

soma

March 29, 2010, March 29, 2010 20:46, permalink

No rating. Login to rate!

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.

342c413e4a47dcd78ce3f8246878f018

Loradae

November 24, 2011, November 24, 2011 16:07, permalink

No rating. Login to rate!

If I were a Teenage Mutant Ninja Turtle, now I'd say “Kowbangua, dude!”

ERROR_BAD_DUPLICATES
342c413e4a47dcd78ce3f8246878f018

Loradae

November 24, 2011, November 24, 2011 16:07, permalink

No rating. Login to rate!

If I were a Teenage Mutant Ninja Turtle, now I'd say “Kowbangua, dude!”

ERROR_BAD_DUPLICATES
342c413e4a47dcd78ce3f8246878f018

Loradae

November 24, 2011, November 24, 2011 16:07, permalink

No rating. Login to rate!

If I were a Teenage Mutant Ninja Turtle, now I'd say “Kowbangua, dude!”

ERROR_BAD_DUPLICATES
5875df08a6edef7f5f3027f90c134648

Unity

November 26, 2011, November 26, 2011 17:08, permalink

No rating. Login to rate!

Brilliance for free; your parents must be a sweetehart and a certified genius.

ERROR_BAD_DUPLICATES
5875df08a6edef7f5f3027f90c134648

Unity

November 26, 2011, November 26, 2011 17:08, permalink

No rating. Login to rate!

Brilliance for free; your parents must be a sweetehart and a certified genius.

ERROR_BAD_DUPLICATES
5875df08a6edef7f5f3027f90c134648

Unity

November 26, 2011, November 26, 2011 17:08, permalink

No rating. Login to rate!

Brilliance for free; your parents must be a sweetehart and a certified genius.

ERROR_BAD_DUPLICATES

Your refactoring





Format Copy from initial code

or Cancel