[英]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.