Программа, которая считает количество слогов в файле - PullRequest
0 голосов
/ 13 февраля 2019

У меня есть функция, которая должна считать количество слогов в файле с учетом этих ограничений:

1) Каждая группа смежных гласных (a, e, i, o, u, y) считается какодин слог (например, «ea» в «real» считается одним слогом, а «e..a» в «regal» считается как два слога

2) «e» в концеслова не считается слогом

3) Каждое слово имеет хотя бы один слог, даже если предыдущие правила дают счет ноль.

Учитывая это, я сделал (хотя и довольноcrummy) функция для подсчета количества слогов в файле

Я пытался создать эту функцию многими различными способами, но этот способ имеет для меня смысл, а также дает мне разумный (не совсем, но вбольшая схема вещей, которые он делает) оценка истинного ответа.

int syllableCount(char **str)
{
    int i = 0;
    int q = 0;
    int syllableCounter = 0;

    for (i = 0; i < lineCount; i++)
    {
        for (q = 0; q <= strlen(str[i]); q++)
        {
            if (str[i][q] == 'A' || str[i][q] == 'a' ||
                str[i][q] == 'E' || str[i][q] == 'e' ||
                str[i][q] == 'I' || str[i][q] == 'i' ||
                str[i][q] == 'O' || str[i][q] == 'o' ||
                str[i][q] == 'U' || str[i][q] == 'u' ||
                str[i][q] == 'Y' || str[i][q] == 'y')
            {
                syllableCounter++;
            }
            if ((str[i][q] == 'E' && str[i][q + 1] == ' ') ||
                (str[i][q] == 'e' && str[i][q + 1] == ' ') ||
                (str[i][q] == 'E' && str[i][q + 1] == '\n') ||
                (str[i][q] == 'e' && str[i][q + 1] == '\n') ||
                (str[i][q] == 'E' && str[i][q + 1] == '.') ||
                (str[i][q] == 'e' && str[i][q + 1] == '.') ||
                (str[i][q] == 'E' && str[i][q + 1] == ';') ||
                (str[i][q] == 'e' && str[i][q + 1] == ';') ||
                (str[i][q] == 'E' && str[i][q + 1] == ':') ||
                (str[i][q] == 'e' && str[i][q + 1] == ':') ||
                (str[i][q] == 'E' && str[i][q + 1] == '!') ||
                (str[i][q] == 'e' && str[i][q + 1] == '!') ||
                (str[i][q] == 'E' && str[i][q + 1] == '?') ||
                (str[i][q] == 'e' && str[i][q + 1] == '?'))
            {
                syllableCounter--;
            }
            if ((str[i][q] == 'A' || str[i][q] == 'a' ||
                 str[i][q] == 'E' || str[i][q] == 'e' ||
                 str[i][q] == 'I' || str[i][q] == 'i' ||
                 str[i][q] == 'O' || str[i][q] == 'o' ||
                 str[i][q] == 'U' || str[i][q] == 'u' ||
                 str[i][q] == 'Y' || str[i][q] == 'y') &&
                (str[i][q + 1] == 'A' || str[i][q + 1] == 'a' ||
                 str[i][q + 1] == 'E' || str[i][q + 1] == 'e' ||
                 str[i][q + 1] == 'I' || str[i][q + 1] == 'i' ||
                 str[i][q + 1] == 'O' || str[i][q + 1] == 'o' ||
                 str[i][q + 1] == 'U' || str[i][q + 1] == 'u' ||
                 str[i][q + 1] == 'Y' || str[i][q + 1] == 'y'))
            {
                syllableCounter--;
            }
            if ((str[i][q] != 'A' || str[i][q] != 'a' ||
                 str[i][q] != 'E' || str[i][q] != 'e' ||
                 str[i][q] != 'I' || str[i][q] != 'i' ||
                 str[i][q] != 'O' || str[i][q] != 'o' ||
                 str[i][q] != 'U' || str[i][q] != 'u' ||
                 str[i][q] != 'Y' || str[i][q] != 'y') &&
                (str[i][q + 1] == ' ' || str[i][q + 1] == '\n'))
            {
                syllableCounter++;
            }
        }
    }
    return syllableCounter;
}

С моим тестовым файлом я получил 54 слога, а реальный ответ - 32. Что заставляет меня отключиться на 22!?

PS: вот текст в файле, который я использовал:

"Красное готовое платье было сделано для вас!Это должно было быть готово завтра.Какого цвета был платье?О, это было красным! "

Все ошибки в написании и пробелах сделаны специально

1 Ответ

0 голосов
/ 13 февраля 2019

Ваш код слишком сложен.

Правила в исходной постановке задачи невероятно просты.Для каждого слова вам нужно посчитать, сколько разных гласных групп вы встретите.Предложение в комментариях об использовании конечного автомата абсолютно правильно.Однако вам не нужна сложная машина.Вам просто нужно отследить несколько основных состояний.

Как минимум, я предлагаю следующие состояния:

int in_word = 0;         // non-zero if currently processing a word
int in_vowels = 0;       // non-zero if currently processing group of vowels
int is_silent_e = 0;     // non-zero if the last vowel processed was an 'e'
int vowel_groups = 0;    // counts the number of vowel groups encountered in current word

Теперь, с разумными состояниями, как указано выше, вот схема того, как их использовать:

for (char *p = str[i], *end = p + strlen(str[i]) + 1; p != end; ++p)
{
    char c = tolower(*p);
    if (isalpha(c))
    {
        // starting a new word?
        if (!in_word) {
            in_word = 1;
            in_vowels = 0;
            is_silent_e = 0;
            vowel_groups = 0;
        }

        // do we have a vowel?
        if (strchr("aeiouy", c)) {
            if (!in_vowels) {
                /**** WRITE ME ****/
                ++vowel_groups;
            } else {
                /**** WRITE ME ****/
            }
        } else if (in_vowels) {
            // no longer in vowel group
            /**** WRITE ME ****/
        }
    }
    else if (in_word)
    {
        // No longer in a word -- update syllable count and reset
        vowel_groups -= is_silent_e;

        /**** WRITE ME ****/
    }
}

Я оставил для вас некоторую логику для заполнения. Если вы все сделаете правильно, вы получите ответ 32 для вашего примера ввода.

Обратите внимание на специальный циклусловие, обеспечивающее нулевой терминатор строки, также обрабатывается циклом.Это обеспечит выполнение теста конца слова, даже если последний символ в строке является символом слова.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...