这是我为家庭作业写的一段代码。它似乎有用,但我想知道我是否错过了什么。
任务是实现一个函数(这里:Countwords
),它计算char *中的所有单词。不应使用库函数。
namespace {
bool IsPrintable(char c) {
return c >= '!' && c <= '~';
}
void SkipPrintable(const char *&s) {
do {
s++;
} while (IsPrintable(*s));
}
bool IsWhiteSpace(char c) {
return c == ' ' || c == '\t' || c == '\n';
}
void SkipWhitespace(const char *&s) {
while (IsWhiteSpace(*s)) {
s++;
}
}
} // namespace
int CountWords(const char *s) {
int count = 0;
while (*s != '\0') {
SkipWhitespace(s);
if (IsPrintable(*s)) {
count++;
SkipPrintable(s);
}
}
return count;
}
答案 0 :(得分:4)
您可以通过线性复杂度解决此问题。人们不能以较低的复杂性做同样的事情。因此,您无法显着改进您的算法。
答案 1 :(得分:1)
没有办法显着改进算法,但你可以通过使用一个类来表示解析器的状态(例如当前索引和字符串本身,以便它不需要被传遍了。您还可以通过实现一个带有SkipPrintable
函数指针的SkipWhitespace
函数,然后传入SkipWhile
来删除bool (*ShouldSkip)(char)
和&IsWhitespace
之间的部分冗余。或&IsPrintable
。
答案 2 :(得分:0)
我同意上述所有内容。 你的代码足够好,重要的是它的线性因此它的效率 你可能考虑的唯一一件事就是简化它就像
bool newWord = true;
int count = 0;
while(*s != '\0')
{
if(!IsWhiteSpace(*s))
{
if(newWord)
{
newWord = false;
count++;
}
}
else
{
newWord = true;
}
s++;
}
但同样,我认为您的实施没有问题
答案 3 :(得分:0)
为了简化算法(在可读性而非计算复杂性方面),您可以计算单词开头(其中非空白字符跟在空白之后,或者是字符串中的第一个字符)。
char previousCharacter=' ';
int wordsCount=0;
while(*s)
{
if(IsWhiteSpace(previousCharacter) && !IsWhiteSpace(*s))
++wordsCount;
previousCharacter=*s;
++s;
}