我正在阅读一些C编程问题,我想确保我的基础知识有所下降。目前我正在讨论一个词:
问:写一个函数,它将确定给定字符串中有多少个单词。你可以假设一个或多个 连续的空格是单词之间的分隔符,并且传递给函数的字符串为空终止。
我得到了工作,但效率很重要。我想知道它是如何改进的。除#include(stdio.h)之外,必须使用指针而没有其他库谢谢!
#include <stdio.h>
int word_counter(char string[])
{
//We start with first word unless we have a empty string then we have no words
int count;
if(*string!='\0'){
count=1;
}
else{
count=0;
return 0;
}
//while we dont reach the end of the string
while(*string!='\0'){
//if we detect a whitespace
if(*string==' '){
//get previous character
string--;
// If previous character is not a space we increase the count
// Otherwise we dont since we already counted a word
if(*string!=' '){
count++;
}
//return pointer to current character
string++;
}
// set pointer to next character
string++;
}
return count;
}
//just to test if it works
int main(void)
{
char str[] = "Hello World!";
printf("How many words? = %i\n", word_counter(str));
return 0;
}
答案 0 :(得分:0)
查看代码,我发现空字符串的初始条件有一个特殊情况。有时,尽早获得初始条件会简化算法的其余部分,有时您可以通过更改查看问题的方式来消除它。这次是第二次。
如果您将此视为计算单词之间的边界,则算法会变得更简单。有两种方法可以从正面和背面定义单词边界。
" Prestidigitation \n"
^ ^
front back
我们是否在空白字符后面寻找非空白字符?或者我们是否在非空白字符后寻找空白字符?
你也有在字符串(string--
)中向后看的代码,这通常是不安全的,因为如果字符串以空格开头怎么办?然后你已经从弦上向后走了,所以应该避免向后移动。
最后,问题是字符串末尾是否有空格。我们必须特殊情况下字符串的结尾。
所以看第一个单词边界是要走的路:一个空白字符后面的非空白字符。我们将跟踪前一个角色的状态(last_was_space
以下),而不是向后看。
这是一个空格字符后面的非空格字符。如果字符串不以空格开头怎么办?
"Basset hounds got long ears."
^
What about this?
由于我们有last_was_space
,我们可以将它初始化为true并假装字符串的开头以空格开头。这也处理领先的空格,如" this is four words"
。
最后,有更多类型的空间,而不仅仅是空格,如tab和换行以及其他奇特的东西。我们可以使用if( *space == ' ' || *space == '\n' == ... )
来使事情整洁有效,而不是写switch
。这是一种罕见的案例,你想利用它的“堕落”机制为多个案件做同样的事情。
#include <stdio.h>
// Note that it's `const` since we don't touch the string memory.
int word_counter(const char string[]) {
// Start with no words.
int count = 0;
// Pretend every word starts with space.
short last_was_space = 1;
// Using a for loop to make the movement of the pointer more apparent
for( ; *string!='\0'; string++ ) {
// A switch can be faster than an if/else if.
switch( *string ) {
// There's more than one type of whitespace.
// These are from isspace().
// It takes advantage of switch's fall through.
case ' ':
case '\t':
case '\n':
case '\r':
case '\v':
case '\f':
// Remember we saw a space.
last_was_space = 1;
break;
default:
if( last_was_space ) {
// Non-whitespace after space, count it
count++;
// Remember we didn't see a space.
last_was_space = 0;
}
break;
}
}
return count;
}
通常情况下,我会使用stdbool.h中的bool
和ctype.h中的isspace
,但您的练习只能使用stdio.h
。