繁体   English   中英

找出字符串中最长单词的长度。 C语言

[英]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 函数(如strspnstrcspn而不是检查每个字符是否为空白。

这是一个演示程序,展示了如何实现该功能。

#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

另一种方法是编写两个类似于strspnstrcspn函数来处理空格和标点符号。

这是一个演示程序。

#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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM