Удалить слова из предложения

Вообщем у меня задание по работе с текстом, указателями и динамической памятью, я код вообщем то готов только одна функция работает некоректно. Вот что она должна делать "Все предложения, в которых есть цифры внутри слов, должны быть удалены (это не касается слов, которые начинаются/заканчиваются цифрами). Если слово начинается с цифры, но имеет и цифру в середине, удалять его все равно требуется (4a4a)." Помогите пожалуйста написать функцию для этого задания на языке СИ буду очень признателен, так как не хочется вылетать с первого курса. И функция должна иметь вид int check_digits(char* text, int start, int end) вот что требуется в задаче Напишите программу, которая форматирует некоторый текст и выводит результат на консоль.

На вход программе подается текст, который заканчивается предложением "Dragon flew away!".

Предложение (кроме последнего) может заканчиваться на:

. (точка) ; (точка с запятой) ? (вопросительный знак) Программа должна изменить и вывести текст следующим образом:

Каждое предложение должно начинаться с новой строки. Табуляция в начале предложения должна быть удалена. Все предложения, в которых есть цифры внутри слов, должны быть удалены (это не касается слов, которые начинаются/заканчиваются цифрами). Если слово начинается с цифры, но имеет и цифру в середине, удалять его все равно требуется (4a4a). Текст должен заканчиваться фразой "Количество предложений до n и количество предложений после m", где n - количество предложений в изначальном тексте (без учета терминального предложения "Dragon flew away!") и m - количество предложений в отформатированном тексте (без учета предложения про количество из данного пункта).

  • Порядок предложений не должен меняться

  • Статически выделять память под текст нельзя

  • Пробел между предложениями является разделителем, а не частью какого-то предложения

и вот мой код:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define COUNT_CHARS 1000
#define STOP_SENTENCE "Dragon flew away!"


int check_digits(char* text, int start, int end) {
    for (int i = start; i < end; i++) {
        if (isdigit(text[i])) {
            return 0;
        }
    }
    return 1;
}

int add_to_newtext(char* text, char* new_text, int start, int end, int* new_text_index) {
    while (text[start] == ' ') {
        start++;
    }
    for (int i = start; i <= end; i++) {
        new_text[*new_text_index] = text[i];
        (*new_text_index)++;
    }
    new_text[(*new_text_index)++] = '\n';
    return 0;
}

char* get_text() {
    char* text = malloc(COUNT_CHARS);
    int curent_size = 0;
    int size = COUNT_CHARS;
    char c;
    while (1) {
        c = getchar();
        if (curent_size >= size - 1) {
            size += COUNT_CHARS;
            text = realloc(text, size);
        }
        text[curent_size] = c;
        curent_size++;
        if (strstr(text, STOP_SENTENCE) != NULL) {
            break;
        }
    }
    text[curent_size] = '\0';
    return text;
}

int main() {
    char* text = get_text();
    int len_text = strlen(text);
    char* new_text = malloc(len_text);
    int sentences_before = 0;
    int count_delete_sentences = 0;
    int start = 0;
    int end = 0;
    int new_text_index = 0;
    for (int i = 0; i < len_text; i++) {
        if (text[i] == '.' || text[i] == '?' || text[i] == ';') {
            sentences_before++;
            end = i;
            if (check_digits(text, start, end)) {
                add_to_newtext(text, new_text, start, end, &new_text_index);
            }
            else {
                count_delete_sentences++;
            }
            start = end + 1;
        }
    }
    new_text[new_text_index + 1] = '\0';
    for (int i = 0; i < new_text_index; i++) {
        printf("%c", new_text[i]);
    }
    printf("%s\n", STOP_SENTENCE);
    printf("Êîëè÷åñòâî ïðåäëîæåíèé äî %d è êîëè÷åñòâî ïðåäëîæåíèé ïîñëå %d\n", sentences_before, sentences_before - count_delete_sentences);
    free(text);
    free(new_text);
    return 0;
}

Ответы (1 шт):

Автор решения: MBo

Как я понял, удалению подлежат слова, в которых и слева и справа от цифр есть буквы.

Думаю, что регулярные выражения здесь (в учебной задаче) использовать нельзя, а вот простейший конечный автомат (машину состояний) сделать нетрудно:

Вначале состояние int state = 0

Если встретили букву, и состояние чётное (state%2==0), то делаем state++
(так объединяем переходы из 0 в 1 и из 2 в 3)

Если встретили цифру, и состояние нечётное (state%2) или (state==1), то тоже делаем state++

Если state достигло значения 3, то мы нашли нужную комбинацию, и выходим с результатом 0

int check_digits(char* text, int start, int end) {
    int state = 0;
    for (int i = start; i < end; i++) {
        if (isdigit(text[i]) && (state==1)) 
            state++;
        if (isalpha(text[i]) && (state%2==0)) 
            state++;
        if (state==3) 
           return 0;  
    }
    return 1;
 }  
→ Ссылка