CS50作业2:Readability代码计算逻辑异常问题排查
CS50 Problem Set 2: Readability 计算逻辑错误排查
在完成CS50的Problem Set 2: Readability任务时,编写的C语言代码可正确统计文本的字母、单词和句子数量,但可读性指数的计算逻辑存在异常。测试句子"There are more things in Heaven and Earth, Horatio, than are dreamt of in your philosophy."时,得到的等级为7级,而非预期的9级。
原代码如下:
#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) { string text = get_string("Text: "); int number = count_letters(text); int number_of_words = count_words(text); int sentences = count_sentences(text); int L = (number / number_of_words) * 100; int S = (sentences/number_of_words) * 100; int index = (0.0588 * L) - (0.296 * S) - 15.8; if (index < 16 && index > 1) { printf("Text: %s\n %i letters\n %i words\n %i sentences\n", text, number, number_of_words, sentences); printf("L:%i\n", L); printf("S:%i\n", S); printf("Grade:%i\n", index); printf("Grade %i\n", (int) round(index)); } else if (index < 1) { printf("Before Grade 1\n"); } else { printf("Grade: 16+\n"); } } //sentence counter int sentences = 0; int count_sentences(string text) { int lengths = strlen(text); for (int i = 0; i < lengths; i++) { if(text[i] == '.' || text[i] == '?' || text [i] == '!') { sentences = sentences + 1; } else { sentences = sentences + 0; } } return sentences; } //word counter int words = 1; int count_words(string text) { int length = strlen(text); for (int j = 0; j < length; j++) { if(isspace(text[j])) { words = words + 1; } else { words = words + 0; } } return words; } //letter counter int letters = 0; int count_letters(string text) { int len = strlen(text); for(int i = 0; i < len; i++) { if(isalpha(text[i])) { letters = letters + 1; } else { letters = letters + 0; } } return letters; }
错误原因分析
1. 整数除法导致精度丢失
代码中计算L(每100单词的字母数)和S(每100单词的句子数)时使用了整数除法:
int L = (number / number_of_words) * 100; int S = (sentences/number_of_words) * 100;
整数除法会直接截断小数部分,比如测试句中字母数为56,单词数为18,56 / 18的整数结果是3,乘以100得到300,但实际正确值应为(56.0 / 18) * 100 ≈ 311.11。这种精度丢失会直接导致后续可读性指数计算严重偏差。
2. 可读性指数变量类型错误
代码中将浮点数运算结果赋值给int类型的index:
int index = (0.0588 * L) - (0.296 * S) - 15.8;
浮点数结果会被强制截断为整数,比如正确计算出的index可能是8.xx,截断后变成8,再经过round()得到8,但实际预期是9。需要用浮点数类型存储index,保留小数部分后再取整。
3. 全局变量的累加问题
统计函数使用了全局变量letters、words、sentences,这些变量不会在每次调用函数时重置为0。如果程序多次处理文本,统计值会累加导致错误。即使单次运行,这种设计也不符合函数的独立性原则,容易引发潜在bug。
修正方案
- 将
L、S、index改为浮点类型,使用浮点数运算:
float L = ((float)number / number_of_words) * 100; float S = ((float)sentences / number_of_words) * 100; float index = (0.0588 * L) - (0.296 * S) - 15.8;
- 将统计函数中的全局变量改为局部变量,每次调用时初始化:
比如修改count_letters函数:
int count_letters(string text) { int letters = 0; // 局部变量,每次调用初始化 int len = strlen(text); for(int i = 0; i < len; i++) { if(isalpha(text[i])) { letters++; } } return letters; }
同理修改count_words和count_sentences函数,移除全局变量,改用局部变量。
- 最终等级计算使用
round()函数取整,再判断输出:
int grade = (int)round(index); if (grade >= 16) { printf("Grade 16+\n"); } else if (grade < 1) { printf("Before Grade 1\n"); } else { printf("Grade %d\n", grade); }
内容的提问来源于stack exchange,提问作者Faith
相关产品推荐
相关产品推荐

