[英]Find the length of the longest word in a string. C language
问题:我似乎无法让我的测试用例 4 工作。
题:
写一个C函数,接受一个英文句子作为参数,返回句子中最长单词的长度。 例如,如果句子是“I am Tim.”,则返回句子3中最长的单词“time”的长度。
测试案例 1:
Enter a string: I am lee.
longWordLength(): 3
测试案例 2:
Enter a string: There are two disciples in the class.
longWordLength(): 9
测试案例 3:
Enter a string: Good night!
longWordLength(): 5
测试案例 4:
Enter a string: Jovial
longWordLength(): 6
这是我到目前为止的代码:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int longWordLength(char *s);
int main()
{
char str[80], *p;
printf("Enter a string: \n");
fgets(str, 80, stdin);
if (p=strchr(str,'\n')) *p = '\0';
printf("longWordLength(): %d\n", longWordLength(str));
return 0;
}
int longWordLength(char *s)
{
int i, count, max;
max = 0;
count = 0;
while( *(s) != '\0' )
{
if ( *(s) != '\0' && *(s) != ' ' && *(s) != '.' )
{
count++;
printf("current count is %d\n", count);
}
else
{
if(count>max)
{
max = count;
printf("There is a new max! It is %d\n", max);
count = 0;
}
count = 0;
printf("count is resetted!\n");
}
s++;
printf("reach the end of the while loop\n");
}
printf("current max outside while loop is: %d\n", max);
printf("exited\n");
return max;
}
当关键字位于行尾时,您的代码不起作用。
那是因为您的max
在该 while 循环内更新,而 while 循环在找到空字符时终止。 由于空字符始终附加到输入字符串的末尾,因此字符串中的最后一个单词不会影响输出。 在这种边缘情况下,循环不会在最终迭代中提供执行else
块的机会。
事实上,您的代码只会通过测试用例 2,因为所有其他用例都包含输入字符串末尾的关键字。
即使您纠正了这一点,如果句子包含句点以外的标点符号,您的代码仍然可能会失败。
例如: “测试用例!”
新代码将计算“案例!” 作为长度大于“Test”或“Case”长度的 5 个单词,并给出错误答案。
您可以查看 C 必须提供的一些库 函数,以帮助您通过所有边缘情况。
如果您需要更多帮助,我已对您的代码进行了必要的修改:
while( *(s) != '\0' )
{
// if ( *(s) != '\0' && *(s) != ' ' && *(s) != '.' )
// Why check the null character again?
// Spaces and period will not be the only punctuation marks
// You can check for all punctuation marks using ispunct() from <ctype.h>
if (!isspace(*s) && !ispunct(*s))
{
count++;
printf("current count is %d\n", count);
// You can update max here
if(count > max)
{
max = count;
printf("There is a new max! It is %d\n", max);
}
}
/*
Now you can eliminate this block of code
else
{
if(count>max)
{
max = count;
printf("There is a new max! It is %d\n", max);
count = 0;
}
count = 0;
printf("count is resetted!\n");
}
*/
// You can reset count after all that
else
{
count = 0;
printf("count is resetted!\n");
}
s++;
printf("reach the end of the while loop\n");
}
该代码假定输入将是一个正确的英语句子。
PS 这个答案为我赢得了 1K 的声誉:)
对于初学者来说,函数参数应该用限定符const
声明,因为在函数内传递的字符串没有被改变。 并且函数返回类型应该是size_t
。 它是函数strlen
的返回类型或sizeof
运算符返回的值的sizeof
。
size_t longWordLength( const char *s);
字符串的最后一个单词不参与最大单词的计算,因为只要下一个字符是终止零字符'\\0'
,循环就会停止其迭代。
在循环外处理最后一个单词的大小将是一个坏主意。 所有处理都应在循环内完成。
此外,您的函数不考虑除点以外的标点符号。
例如像这样的句子"How are you?"
你的函数会给出错误的结果。
您可以使用标准 C 函数(如strspn
和strcspn
而不是检查每个字符是否为空白。
这是一个演示程序,展示了如何实现该功能。
#include <stdio.h>
#include <string.h>
#include <ctype.h>
size_t longWordLength( const char *s )
{
const char *delim = " \t";
size_t max = 0;
while ( *s )
{
s += strspn( s, delim );
if ( *s )
{
const char *first = s;
s += strcspn( s, delim );
const char *last = s;
while ( last != first && ispunct( ( unsigned char )*( last - 1 ) ) )
{
--last;
}
if ( max < last - first ) max = last - first;
}
}
return max;
}
int main(void)
{
const char *s = "Why are not you using string functions?!";
printf( "The size of the longest word is %zu\n", longWordLength( s ) );
return 0;
}
程序输出是
The size of the longest word is 9
另一种方法是编写两个类似于strspn
和strcspn
函数来处理空格和标点符号。
这是一个演示程序。
#include <stdio.h>
#include <string.h>
#include <ctype.h>
size_t count_non_alpha( const char *s )
{
size_t n = 0;
while ( isblank( ( unsigned char )s[n] ) || ispunct( ( unsigned char )s[n] ) )
{
++n;
}
return n;
}
size_t count_alpha( const char *s )
{
size_t n = 0;
while ( s[n] && !isblank( ( unsigned char )s[n] ) && !ispunct( ( unsigned char )s[n] ) )
{
++n;
}
return n;
}
size_t longWordLength( const char *s )
{
size_t max = 0;
while ( *s )
{
s += count_non_alpha( s );
if ( *s )
{
const char *first = s;
s += count_alpha( s );
if ( max < s - first ) max = s - first;
}
}
return max;
}
int main(void)
{
const char *s = "Why are not you using string functions?!";
printf( "The size of the longest word is %zu\n", longWordLength( s ) );
return 0;
}
程序输出与上图相同。
请参阅我对您原始问题的评论。
您可以通过在while
循环之后添加以下代码来解决您的问题。
if (*(s - 1) != ' ' && *(s - 1) != '.' )
{
if(count>max)
{
max = count;
printf("There is a new max! It is %d\n", max);
}
}
该代码检查输入字符串中的最后一个字符。 如果它不是单词终止字符,则您没有将最后一个单词与循环中的当前max
进行比较,因此您在循环完成后进行比较。
isalpha()
检查字符类型'\\0'
不要忘记计算最后一个单词#include <stdio.h>
#include <ctype.h>
unsigned longest_word(char *str)
{
unsigned length,longest;
for(longest=length = 0; ; str++) {
if (isalpha(*str)) { length++; continue; }
if (length > longest) longest = length;
length = 0;
if (!*str) break;
}
return longest;
}
int main(void)
{
char * string1 = "The longest word is short";
char * string2 = "The longest word is unbelievable";
printf("%s: %u\n", string1, longest_word( string1) );
printf("%s: %u\n", string2, longest_word( string2) );
return 0;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.