Предложение, очень быстрое, потому что строка выполняется только один раз, и в куче нет динамического (де) распределения.См. Комментарии в коде:
#include <stdio.h>
#include <ctype.h>
int numberOfSmallLetterWords(char* str)
{
int nWords = 0;
int inWord = 0;
int inSpaces = 1; /* not 0 to allow a word to start at the first character */
while (*str) {
if (islower(*str)) {
/* compatible with a word */
if (inSpaces) {
/* start a potential new word */
inSpaces = 0;
inWord = 1;
}
/* else nothing change:
- if we was in a word we are still
- if we was not in word nor spaces we are still in none of them
*/
}
else if (isspace(*str)) {
if (inWord) {
/* spaces after a potential word validates it */
nWords += 1;
inWord = 0;
}
inSpaces = 1;
}
else
/* not in spaces nor in word */
inWord = inSpaces = 0;
str += 1;
}
/* warning do not forget to count a possible word at the end */
return (inWord) ? (nWords + 1) : nWords;
}
int main()
{
printf("%d\n", numberOfSmallLetterWords(" it is a sMall World after all! "));
return 0;
}
Исполнение:
4
и под valgrind:
==9376== Memcheck, a memory error detector
==9376== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==9376== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==9376== Command: ./a.out
==9376==
4
==9376==
==9376== HEAP SUMMARY:
==9376== in use at exit: 0 bytes in 0 blocks
==9376== total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==9376==
==9376== All heap blocks were freed -- no leaks are possible
==9376==
==9376== For counts of detected and suppressed errors, rerun with: -v
==9376== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 6)
Если вы не хотите использовать ctype islower и isspace :
int islower(char c)
{
return ((c >= 'a') && (c <= 'z'));
}
int isspace(char c)
{
switch (c) {
case ' ':
case '\t':
case '\n':
case '\r':
/* may be more cases */
return 1;
default:
return 0;
}
}
, предупреждающие, что эти определения менее переносимы, чем версия ctype