You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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。

修正方案

  1. 将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;
  1. 将统计函数中的全局变量改为局部变量,每次调用时初始化:
    比如修改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函数,移除全局变量,改用局部变量。

  1. 最终等级计算使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 00:37:55