CS50 Problem Set 2 文本分级程序结果异常求助
CS50 Problem Set 2 文本分级程序错误修复
问题现象
- 输入文本
"One fish. Two fish. Red fish. Blue fish."时,程序错误输出Grade 2,预期输出Before Grade 1 - 一段需判定为
Grade 16+的文本,程序输出Grade 14
原代码
#include <cs50.h> #include <stdio.h> #include <string.h> #include <ctype.h> #include <math.h> int count_letters(string text); int count_word(string text); int count_sentences(string text); int letters; int words; int sentences; int main(void) { string text = get_string("Text: "); printf("Text: %s\n", text); count_letters(text); count_word(text); count_sentences(text); float L = 100 * (letters / words); float S = 100 * (sentences / words); int index = round(0.0588 * L - 0.296 * S - 15.8); if (index < 1) { printf("Before Grade 1\n"); } else if (index > 16) { printf("Grade 16+\n"); } else { printf("Grade: %i\n", index); } } int count_letters(string text) { letters = 0; for (int i = 0; i < strlen(text); i++) { if ((text[i] >= 65 && text[i] <= 99) || (text[i] >= 97 && text[i] <= 122)) { letters++; } } return letters;} int count_word(string text) { words = 1; for (int i = 0; i < strlen(text); i++) { if (isspace(text[i])) { words++; } } return words;} int count_sentences(string text) { sentences = 0; for (int i = 0; i < strlen(text); i++) { if (text[i] == 33 || text[i] == 46 || text[i] == 63) { sentences++; } } return sentences; }
错误分析与修复
1. 整数除法导致精度丢失
计算L和S时,letters、words、sentences均为整数,执行letters / words会触发整数除法(直接截断小数部分),导致计算结果严重偏离实际值。比如测试案例中21/8会得到2而非正确的2.625,直接导致分级指数计算错误。
修复:将其中一个操作数转为浮点数,触发浮点除法:
float L = 100.0 * letters / words; float S = 100.0 * sentences / words;
2. 字母判断的ASCII范围错误
count_letters函数中,大写字母的判断范围写为65 <= text[i] <= 99,但大写字母A-Z的ASCII范围是65-90,91-99包含了[、\等非字母字符,会导致字母数统计偏多。
修复:修正大写字母的判断范围,也可直接使用字符常量提高可读性:
if ((text[i] >= 'A' && text[i] <= 'Z') || (text[i] >= 'a' && text[i] <= 'z'))
3. 全局变量优化(可选)
原代码使用全局变量存储统计结果,容易引发意外的变量覆盖问题。建议改为在main中声明局部变量,通过函数返回值获取结果,代码更健壮:
int letters = count_letters(text); int words = count_words(text); int sentences = count_sentences(text);
修复后代码
#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 letters = count_letters(text); int words = count_words(text); int sentences = count_sentences(text); float L = 100.0 * letters / words; float S = 100.0 * sentences / words; int index = round(0.0588 * L - 0.296 * S - 15.8); if (index < 1) { printf("Before Grade 1\n"); } else if (index > 16) { printf("Grade 16+\n"); } else { printf("Grade %i\n", index); } } int count_letters(string text) { int count = 0; for (int i = 0; i < strlen(text); i++) { if ((text[i] >= 'A' && text[i] <= 'Z') || (text[i] >= 'a' && text[i] <= 'z')) { count++; } } return count; } int count_words(string text) { int count = 1; for (int i = 0; i < strlen(text); i++) { if (isspace(text[i])) { count++; } } return count; } int count_sentences(string text) { int count = 0; for (int i = 0; i < strlen(text); i++) { if (text[i] == '!' || text[i] == '.' || text[i] == '?') { count++; } } return count; }
验证结果
输入 "One fish. Two fish. Red fish. Blue fish." 时,统计结果为:
- letters=21,words=8,sentences=4
计算得:L = (21/8)*100 = 262.5,S = (4/8)*100 = 50index = round(0.0588*262.5 - 0.296*50 -15.8) = -15,输出Before Grade 1,符合预期。
内容的提问来源于stack exchange,提问作者Beatriz Martins
相关产品推荐
相关产品推荐

