これは簡単な提案です。もっと良い方法があるかもしれませんが、私はこれが気に入っています。
まず、単語が何でできているかを「知る」ようにしてください。文字だけでできているとしましょう。句読点または「空白」である残りのすべては、セパレーターと見なすことができます。
次に、「システム」には2つの状態があります。1)単語の完成、2)セパレータのスキップです。
スキップ区切りコードのフリーランでコードを開始します。次に、次のセパレーターまたは文字列全体の終わりまで保持される「単語の完成」状態に入ります (この場合は終了します)。これが発生すると、単語が完成したので、単語カウンターを 1 増やし、「区切りをスキップする」状態になります。そしてループは続く。
疑似 C ライク コード:
char *str;
/* someone will assign str correctly */
word_count = 0;
state = SKIPPING;
for(c = *str; *str != '\0'; str++)
{
if (state == SKIPPING && can_be_part_of_a_word(c)) {
state = CONSUMING;
/* if you need to accumulate the letters,
here you have to push c somewhere */
}
else if (state == SKIPPING) continue; // unneeded - just to show the logic
else if (state == CONSUMING && can_be_part_of_a_word(c)) {
/* continue accumulating pushing c somewhere
or, if you don't need, ... else if kept as placeholder */
}
else if (state == CONSUMING) {
/* separator found while consuming a word:
the word ended. If you accumulated chars, you can ship
them out as "the word" */
word_count++;
state = SKIPPING;
}
}
// if the state on exit is CONSUMING you need to increment word_count:
// you can rearrange things to avoid this when the loop ends,
// if you don't like it
if (state == CONSUMING) { word_count++; /* plus ship out last word */ }
関数 can_be_part_of_a_word は、たとえば、読み取った文字が [A-Za-z_] にある場合は true を返し、そうでない場合は false を返します。
(疲労の軽減に重大な誤りを犯していなければ、うまくいくはずです)