Продолжаем проходить курс Computer Science CS50 (Harvard), и в этот раз будем делать задание на расчет уровня сложности текста по индексу Колман-Лиау (readability.c) на языке программирования C. Согласно идее двух авторов метода, можно оценить сложность текста и таким образом распределить книги по классам школы (от простых текстов, где индекс меньше 1, до академически сложных с индексом более 16). Расчет идет по формуле:
index = 0.0588 * L - 0.296 * S - 15.8 ,
где L — среднее количество букв на 100 слов в тексте,
S — среднее количество предложений на 100 слов в тексте.
Алгоритм создания кода:
- Принять ввод текста;
- Посчитать количество букв, слов и предложений в тексте;
- Рассчитать индекс Колман-Лиау и округлить полученное значение;
- Если индекс получится меньше 1, то написать «Before Grade 1», если индекс больше 16 — «Grade 16+», в остальных случаях просто вывести номер Grade.
Решение Игроглаза. Как обычно, я пишу не используя библиотеку cs50.h, тогда как Штукенция ее использует в своем примере ниже.
#include <stdio.h>
#include <string.h>
#include <math.h>
int count_letters (char text);
int main(void)
{
char text[1000];
int letters = 0;
int words = 0;
int sentances = 0;
printf("Text: \n");
// scanf("%s", text); won't work as input as it stops upon ' ' (space)
for (int i = 0; ; i++)
{
scanf("%c", &text[i]);
if ((text[i] >= 'A' && text[i] <= 'Z') ||
(text[i] >= 'a' && text[i] <= 'z'))
letters++;
if (text[i] == ' ')
words++;
switch (text[i])
{
case ('.'): sentances++; break;
case ('!'): sentances++; break;
case ('?'): sentances++; break;
}
if (text[i] == '\n') break;
}
words++; // words +1 cause of last word which doesn't have ' ' space
printf("Letters: %d\n"
"Words: %d\n"
"Sentances: %d\n", letters, words, sentances);
float L = (letters * 100.0) / words; // avg letters per 100 words
float S = (sentances * 100.0) / words; // avg sentances per 100 words
float grade = (0.0588 * L - 0.296 * S - 15.8); // Coleman-Liau index
if (grade < 1)
printf("Before Grade 1");
else if (grade > 15)
printf("Grade 16+");
else
printf("Grade %.0f", round(grade));
getchar();
getchar();
return 0;
}
Решение (Штукенция) с библиотекой cs50:
#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_sentance(string text);
int main(void)
{
string text = get_string("Your text:");
int sum_letters = count_letters(text);
int sum_words = count_words(text);
int sum_sentance = count_sentance(text);
printf("Sum of lettels:%d\n",sum_letters);
printf("Sum of words:%d\n",sum_words);
printf("Sum of sentances:%d\n",sum_sentance);
float L = (100.0*sum_letters)/sum_words;
float S = (100.0*sum_sentance)/sum_words;
float index = 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 %d\n",(int)rint(index));
}
int count_letters(string text)
{
printf("%s\n", text);
int i=0;
int text_lenth=strlen(text);
int sum_letters=0;
for(i=0; i<=text_lenth; i++)
{
if (isalpha(text[i]))
sum_letters+=1;
}
return sum_letters;
}
int count_words(string text)
{
int i=0;
int text_lenth=strlen(text);
int sum_words=1;
for(i=0; i<=text_lenth; i++)
{
if (isspace(text[i]))
sum_words+=1;
}
return sum_words;
}
int count_sentance(string text)
{
int i=0;
int text_lenth=strlen(text);
int sum_sentance=0;
for(i=0; i<=text_lenth; i++)
{
char sent=text[i];
if (sent == '.' || sent == '!' || sent == '?')
sum_sentance+=1;
}
return sum_sentance;
}
Запуск программы и тестирование на примере текста:
«One fish. Two fish. Red fish. Blue fish.»
После проверки багов и стиля кода, программы выглядит так:
#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_sentance(string text);
// Check level of text by complexity
int main(void)
{
string text = get_string("Your text:");
int sum_letters = count_letters(text);
int sum_words = count_words(text);
int sum_sentance = count_sentance(text);
printf("Sum of lettels:%d\n", sum_letters);
printf("Sum of words:%d\n", sum_words);
printf("Sum of sentances:%d\n", sum_sentance);
float L = (100.0 * sum_letters) / sum_words;
float S = (100.0 * sum_sentance) / sum_words;
float index = 0.0588 * L - 0.296 * S - 15.8; // Formula of Colman-Liau index
if (index < 1)
{
printf("Before Grade 1\n");
}
else if (index > 16)
{
printf("Grade 16+\n");
}
else
{
printf("Grade %d\n", (int)rint(index));
}
}
// Count letters in text
int count_letters(string text)
{
printf("%s\n", text);
int i = 0;
int text_lenth = strlen(text);
int sum_letters = 0;
for (i = 0; i <= text_lenth; i++)
{
if (isalpha(text[i])) // Check if this character is alphabetical
{
sum_letters += 1;
}
}
return sum_letters;
}
// Count words in text
int count_words(string text)
{
int i = 0;
int text_lenth = strlen(text);
int sum_words = 1;
for (i = 0; i <= text_lenth; i++)
{
if (isspace(text[i])) // If there is space, so next word started
{
sum_words += 1;
}
}
return sum_words;
}
// Count sentances in text
int count_sentance(string text)
{
int i = 0;
int text_lenth = strlen(text); // Check lenth of string
int sum_sentance = 0;
for (i = 0; i <= text_lenth; i++)
{
char sent = text[i];
if (sent == '.' || sent == '!' || sent == '?') // Checking the number of sentences by punctuation marks
{
sum_sentance += 1;
}
}
return sum_sentance;
}

