有哪些方法可以改善这种实施(显着)?

时间:2011-02-27 19:38:30

标签: c++

这是我为家庭作业写的一段代码。它似乎有用,但我想知道我是否错过了什么。

任务是实现一个函数(这里: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;
}

4 个答案:

答案 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;
}