Функция множественного удаления в связанном списке удаляет только первый экземпляр символа - PullRequest
0 голосов
/ 05 апреля 2019

Я пытаюсь удалить несколько вхождений слова, хранящегося в связанном списке. Однако эти слова хранятся по символу в одном узле, а не как целое слово в списке. Например, розовый фламинго хранится как: T-> h-> e-> -> p-> i-> n-> k-> -> f-> l-> a-> m-> i-> n-> g-> o. Скажем, пользователь хочет найти розовый. Они должны пройти и удалить каждый из этих узлов.

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

void nodeDeletions(struct node** reference_to_headNode, struct node* deleteNode){

    if(*reference_to_headNode == NULL){
        return;
    }
    if(*reference_to_headNode == deleteNode){

        printf("Test A\n");
        *reference_to_headNode = deleteNode->nextNode;
    }
    if(deleteNode->nextNode != NULL){

        printf("Test B\n");
        deleteNode->nextNode->previousNode = deleteNode->previousNode;
    }
    if(deleteNode->previousNode != NULL){

        printf("Test C\n");
        deleteNode->previousNode->nextNode = deleteNode ->nextNode;
    }

    free(deleteNode);
}

void deleteWord(struct node** reference_to_headNode, char word_to_delete[]){

    struct node *tempNode;
    struct node *nextNode;

    int searchIndex = 0;
    int characterIndex = 0;
    const int arraySize = 101;
    const int arraySize2 = 202;

    char searchWordIndex[arraySize];
    char searchWordCopyIndex[arraySize2];

    if(*reference_to_headNode == NULL){
        return;
    }

    else {

        for (tempNode = *reference_to_headNode; tempNode != NULL; tempNode = tempNode->nextNode) {

            searchWordIndex[searchIndex] = tempNode->character;
            searchIndex++;

        }

        strcpy_s(searchWordCopyIndex, searchWordIndex);

        int length_of_searchIndex = strlen(searchWordCopyIndex);
        int length_of_deletionWord = strlen(word_to_delete);

        tempNode = *reference_to_headNode;

        for (searchIndex = 0; searchIndex < length_of_searchIndex; searchIndex++) {

            printf("Test 1\n");
            if(tempNode != NULL) {

                if(tempNode->character == word_to_delete[0]) {

                    for (characterIndex = 0; characterIndex < length_of_deletionWord; characterIndex++) {


                        printf("Test 2\n");
                        if (searchWordCopyIndex[searchIndex] == word_to_delete[characterIndex]) {


                            printf("Test 3\n");
                            if (tempNode->character == word_to_delete[characterIndex]) {

                                printf("Test 4\n");
                                printf("%c\n", tempNode->character);
                                printf("%c\n%c\n", word_to_delete[characterIndex], searchWordCopyIndex[searchIndex]);

                                nextNode = tempNode->nextNode;

                                nodeDeletions(reference_to_headNode, tempNode);

                                tempNode = nextNode;
                            }
                            else {
                                printf("Test 5\n");

                                tempNode = tempNode->nextNode;

                            }

                        }


                    }


                }

            }

            tempNode = tempNode->nextNode;

        }

    }
}

1 Ответ

0 голосов
/ 05 апреля 2019

Уф! Это много блоков с отступами. И много вспомогательных массивов и индексов. И очень длинные имена переменных. :)

По сути, вы имеете дело с тремя различными типами итерации вперед по вещам, которые все присутствуют в вашем коде:

  • Пройти строку символов:

    while (*s) {
        // do stuff with *s
        s++;
    }
    
  • Просматривать связанный список:

    while (p) {
        // do stuff with *p
        p = p->next;
    }
    
  • Просматривать связанный список через ссылку на источник, чтобы вы могли изменить его:

    while (*p) {
        // do stuff with **p
        p = &(*p)->next;;
    }
    

Вам нужно только объединить эти три основных цикла.

Вы можете просмотреть список с помощью третьего метода (потому что вам нужно иметь возможность обновлять заголовок или следующие ссылки при удалении). Для каждого посещаемого вами узла сравните «хвост» этого узла со вспомогательным указателем p и строкой s, используя два других метода одновременно. Когда строка соответствует, *s == '\0' и p указывают на первый узел после слова. Удалите все узлы, перемещая голову до тех пор, пока головка не станет p.

Другими словами:

  • Пройдите по списку с помощью *head.
  • На каждом узле:
    • установить p = *head и s в начало строки;
    • пройти список и слово, пока буквы совпадают;
    • Если *s == '\0', то есть совпадение. Теперь *head указывает на начало слова для удаления в списке, p указывает на первый узел после слова в списке, которое может быть NULL.
    • Если есть совпадение, продвигайтесь *head до *head == p, удаляя узлы по ходу.

Или, в коде:

void delete_word(struct node **head, const char *str)
{
    while (*head) {
        struct node *p = *head;
        const char *s = str;

        while (p && *s && p->c == *s) {
            p = p->next;
            s++;
        }

        if (*s == '\0') {
            while (*head != p) {
                struct node *del = *head;
                *head = (*head)->next;

                delete_node(del);
            }
        } else {    
            head = &(*head)->next;
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...