簡體   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