I am trying to write a function that will count the occurrences of a pattern in a string without overlap. This is what I have right now.
size_t count(char *string, char *pat) {
size_t patternLength = strlen(pat);
size_t stringLength = strlen(string);
size_t count = 0;
char *compareString = malloc(patternLength + 1);
for (int i = 0; i < stringLength; i++) {
if (i + patternLength > stringLength) return count;
strcpy(compareString, &string[i], i+patternLength);
if (strcmp(compareString, pat) == 0) {
count++;
i--;
i+=patternLength; /* non overlapping find */
}
}
free(compareString);
return count;
}
1 Answer 1
Drop the Intermediate String
You're allocating compareString
and strcpy
ing into it just so that you can use strcmp
. But instead, there's also memcmp
, which lets you compare from the original string directly:
Fix the loop condition
You're not really looping from 0
to stringLength
, you're looping from 0
to stringLength - patternLength
. Splitting up those concerns in two is confusing.
Adjusting i
You have:
i--;
i+=patternLength; /* non overlapping find */
We can do both in one:
i += patternLength - 1;
Better solution:
size_t count(char *string, char *pat) {
size_t patternLength = strlen(pat);
size_t stringLength = strlen(string);
size_t count = 0;
for (int i = 0; i < stringLength - patternLength; i++) {
if (memcmp(string+i, pat, patternLength) == 0) {
count++;
i += patternLength - 1;
}
}
return count;
}