首页 > 解决方案 > CS50-pset2:可读性。结果不正确

问题描述

当我运行我的代码时,结果未能根据问题集中给出的文本显示确切的结果。虽然,它显示了等级,但结果是不正确的。文字是:“你喜欢这里还是那里?我不喜欢这里或那里。我在任何地方都不喜欢它们。”(2 年级) 在此处输入图片描述

据说,文本的结果是“2 级”。但是,它会显示所有成绩。

enter code here
int main(void)
{

string s = get_string("Text: ");
printf("%s\n",s);

int count_letters = 0; //To count letters (uppercase & lowercase)
int count_words = 1; //To count words
int count_sentences = 0; //To count sentences
for (int i = 0; i < strlen(s); i++)



if (isalpha(s[i]))
{
    if ((s[i] >= 'a' && s[i] <= 'z' )||( s[i] >= 'A' && s[i] <= 'Z'))
    {
        count_letters++;
    }
if (s[i] == ' ')
{
        count_words++;
}
if (s[i] == '.' || s[i] =='!' || s[i] == '?')
{
       count_sentences++;
}
//printf("%i count_letter(s)\n", count_letters);
//printf("%i count_words(s)\n", count_words);
//printf("%i sentence(s)\n", count_sentences);

//Coleman-Liau index
float L = (count_letters / (float) count_words) * 100;
float S = (count_sentences / (float) count_words) * 100;
int grade = round (0.0588 * L - 0.296 * S -15.8);
  
if (grade < 1)
    {
        printf("Before Grade 1\n");
    }
else if (grade >= 16)
    {
        printf("Grade 16+\n");
    }
else
    {
        printf("Grade %.d\n", grade);
    }
}

}

我的代码有问题吗?如何修复我的代码以获得确切的结果。我已经做这个问题集将近 2 天了:'/. 提前致谢

标签: arraysccs50

解决方案


由于您要计算三个不同的类别,因此我将为每个类别创建一个函数。

例如,根据您的代码,您可以创建一个计算字符的函数(这里不需要isdigit函数,非数字字符已经被算法本身过滤掉了):

int get_letters_count(char *text_str)
{
    int count_letters = 0;

    int text_len = strlen(text_str);

    for (int i = 0; i < text_len; i++) {

        if (   (text_str[i] >= 'a' && text_str[i] <= 'z')
            || (text_str[i] >= 'A' && text_str[i] <= 'Z')
            || (text_str[i] >= '0' && text_str[i] <= '9')) {

            count_letters++;
        }
    }

    return count_letters;
}

这种分解程序的方法将使其更容易开发。

这是基于Coleman–Liau 索引 Wikipedia 页面的非常粗略的实现:

#include <stdio.h>
#include <string.h>
#include <stdbool.h>

int get_letters_count(char *text_str)
{
    int count_letters = 0;

    int text_len = strlen(text_str);

    for (int i = 0; i < text_len; i++) {

        if (   (text_str[i] >= 'a' && text_str[i] <= 'z')
            || (text_str[i] >= 'A' && text_str[i] <= 'Z')
            || (text_str[i] >= '0' && text_str[i] <= '9')) {

            count_letters++;
        }
    }

    return count_letters;
}

int get_words_count(char *text_str)
{
    int count_words = 0;

    int text_len = strlen(text_str);

    for (int i = 0; i < text_len; i++) {

        if (text_str[i] == ' ') {

            count_words++;
        }
    }

    if (count_words)
        count_words++;

    return count_words;
}

bool word_is_acronym(char *word)
{
    bool ret = true;

    for (; *word && *word != ' '; word++) {

        if (   *word != '.'
            && *word < 'A' || *word > 'Z') {

            ret = false;
        }
    }

    return ret;
}

int get_sentences_count(char *text_str)
{
    int count_sentences = 0;
    int text_len = strlen(text_str);

    char *last_word = &text_str[0];

    for (int i = 0; i < text_len; i++) {

        if (   text_str[i] == ' '
            && i < (text_len - 1)) {

            last_word = &text_str[i + 1];
        }

        bool end_mark =    text_str[i] == '.'
                        || text_str[i] == '!'
                        || text_str[i] == '?';

        if (   end_mark           
            && word_is_acronym(last_word) == false) {

            count_sentences++;
        }
    }

    return count_sentences;
}

int main(void)
{
    char text_str[] = "Existing computer programs that measure readability are based "
                      "largely upon subroutines which estimate number of syllables, "
                      "usually by counting vowels. The shortcoming in estimating syllables "
                      "is that it necessitates keypunching the prose into the computer. "
                      "There is no need to estimate syllables since word length in letters "
                      "is a better predictor of readability than word length in syllables. "
                      "Therefore, a new readability formula was computed that has for its "
                      "predictors letters per 100 words and sentences per 100 words. "
                      "Both predictors can be counted by an optical scanning device, and "
                      "thus the formula makes it economically feasible for an organization "
                      "such as the U.S. Office of Education to calibrate the readability of "
                      "all textbooks for the public school system.";

    int count_letters   = get_letters_count(text_str);
    int count_words     = get_words_count(text_str);
    int count_sentences = get_sentences_count(text_str);;

    if (   count_letters   > 0
        && count_words     > 0
        && count_sentences > 0) {

        float L = ((count_letters * 100) / count_words);
        float S = ((count_sentences * 100) / count_words);
        float grade = 0.0588 * L - 0.296 * S - 15.8;

        printf("grade = %.01f\n", grade);

    } else {

        printf("bad input\n");
    }
}

输出:

$ gcc main.c && ./a.out
grade = 14.5

不过,解析文本可能非常棘手。一旦您获得了使用此类已知输入的第一个版本,请尝试扩展您的数据集并不断改进您的程序。

该程序也远非计算效率高。如果这成为瓶颈,您可以优化函数,或者减少将函数分组到单个循环中的循环数。

当然,大多数时候最好从一个粗略的工作解决方案开始并从那里改进,而不是从一开始就尝试一个更复杂/完整的解决方案。


推荐阅读