CS50可读性作业Pset2:年级等级计算结果异常求助
问题描述
已完成CS50 Readability Pset2的大部分功能,仅年级等级输出存在异常:部分文本输入后能返回正确等级,但部分文本无法得到预期结果。例如两段应返回Grade 8的文本中,爱丽丝相关文本结果正确,另一段则错误。
代码实现
#include <cs50.h> #include <stdio.h> #include <string.h> #include <ctype.h> #include <math.h> int count_letters(string text); int count_words(string text); int count_sentences(string text); int main(void) { //ask user for text string text = get_string("Text: "); //calculate number of letters int numLetters = count_letters(text); //calcuate number of words int numWords = count_words(text); //calculate number of sentences int numSentences = count_sentences(text); float L = 100 * (float) numLetters / (float) numWords; // printf("L: %0.4f\n", L); float S = 100 * (float) numSentences / (float) numWords; // printf("S: %0.4f\n", S); int grade_level = round(0.0558 * L - 0.296 * S - 15.8); if (grade_level < 1) { printf("Before Grade 1\n"); } else if (grade_level >= 16) { printf("Grade 16+\n"); } else { grade_level++; printf("Grade %i\n", grade_level); } } int count_letters(string text) { int letters = 0; for(int i = 0; i < strlen(text); i++) { if(isalpha(text[i])) { letters++; } } return letters; } int count_words(string text) { int words = 1; for(int i = 0; i < strlen(text); i++) { if(isspace(text[i])) { words++; } } return words; } int count_sentences(string text) { int sentences = 0; for(int i = 0; i < strlen(text); i++) { if(text[i] == '.' || text[i] == '!' || text[i] == '?') { sentences++; } } return sentences; }
测试文本
两段预期返回Grade 8的文本:
Alice was beginning to get very tired of sitting by her sister on the bank, and of having nothing to do: once or twice she had peeped into the book her sister was reading, but it had no pictures or conversations in it, "and what is the use of a book," thought Alice "without pictures or conversation?"
When he was nearly thirteen, my brother Jem got his arm badly broken at the elbow. When it healed, and Jem's fears of never being able to play football were assuaged, he was seldom self-conscious about his injury. His left arm was somewhat shorter than his right; when he stood or walked, the back of his hand was at right angles to his body, his thumb parallel to his thigh.
问题原因与修复
问题根源
在main函数的else分支中,错误地对计算得到的grade_level执行了grade_level++操作。根据Coleman-Liau指数公式,计算结果本身就是对应的年级等级,额外加1会导致结果偏高:
- 爱丽丝文本的计算结果为7,加1后得到8,恰好符合预期,掩盖了错误;
- 第二段文本的计算结果为8,加1后得到9,导致输出错误。
修复方案
删除else块中的grade_level++;语句,修改后的代码片段如下:
else { printf("Grade %i\n", grade_level); }
修改后,两段测试文本都会正确返回Grade 8。
内容的提问来源于stack exchange,提问作者ethanhallstar05

