首页 > 解决方案 > 尝试在插入过程中消除列表中的重复项

问题描述

我正在编写一个 C 程序,它获取 CSV 格式的书籍数据作为输入(ISBN 代码、标题、作者)并创建一个排序的链表。该列表按作者排序,然后按标题排序。对于每本书,它需要跟踪输入了多少本书籍。为此,我需要消除列表中的所有重复项,并且每次遇到重复项时,将 book 结构中的“totalCopies”计数器加 1。我可以创建一个在所有输入都注册后解析列表的函数,但我觉得在用户获取输入时这样做更有效。

下面报告了感兴趣的函数,每次输入一本书时都会调用它:

void insertBook(BookPtr *listPtr, const char *isbn, const char *title, const char *author) { 
    // new node
    BookPtr newPtr = malloc(sizeof(Book));
    if (newPtr != NULL) {
        // initializing the new node      
        strcpy(newPtr->isbn, isbn);
        strcpy(newPtr->title, title); 
        strcpy(newPtr->author, author);        
        newPtr->nextPtr = NULL;

        BookPtr previousPtr = NULL;
        BookPtr currentPtr = *listPtr;

        while (currentPtr != NULL && strcmp(author, currentPtr->author) > 0) {            
            previousPtr = currentPtr;
            currentPtr = currentPtr->nextPtr;
        }
        if (previousPtr == NULL) { //empty list
            newPtr->nextPtr = *listPtr;            
            *listPtr = newPtr;        
        } else {
            while (currentPtr != NULL && strcmp(title, currentPtr->title) > 0 && !(strcmp(author, currentPtr->author))) {            
                previousPtr = currentPtr;
                currentPtr = currentPtr->nextPtr;
            }
            if(!(strcmp(previousPtr->isbn, newPtr->isbn))) { //this is the part that doesn't work. it should check if the new book and the one in the position where i would insert it have the same isbn code
                currentPtr->totCopies = (currentPtr->totCopies) + 1;
            } else {  
                previousPtr->nextPtr = newPtr;
                newPtr->nextPtr = currentPtr;
            }    
        }    
    }
    else {
        puts("Error");    
    }
}

这就是我试图将要插入的新书与将要插入的列表中的点之前的书进行比较的方式。

if(!(strcmp(previousPtr->isbn, newPtr->isbn)))

这似乎不起作用。previousPtr 没有像我预期的那样指向前一个节点,而是指向其他元素,但我还不能弄清楚究竟是什么让它指向它们。我希望它指向应该插入新书的位置之前的最后一个节点,因为程序在while循环中滚动了列表,但事实并非如此。

您可以在下面找到我的程序中的部分代码,足以重现该问题。

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


struct book {
    char isbn[7];
    char title[151];
    char author[151];
    int totCopies;
    struct book *nextPtr;
};

typedef struct book Book;
typedef Book *BookPtr;


Book getBook() {
    Book book;

    char data[212];

    fgets(data, sizeof(data), stdin);

    char *field;

    field = strtok(data, ",\n");
    if(field != NULL) {
        strcpy(book.isbn, field);
    }
    field = strtok(NULL, ",\n");
    if(field != NULL) {
        strcpy(book.title, field);
    }
    field = strtok(NULL, ",\n");
    if(field != NULL) {
        strcpy(book.author, field);
    }

    book.totCopies = 0;

    return book;

}

void insertBook(BookPtr *listPtr, const char *isbn, const char *title, const char *author) { 
    // new node
    BookPtr newPtr = malloc(sizeof(Book));
    if (newPtr != NULL) {
        // initializing the new node      
        strcpy(newPtr->isbn, isbn);
        strcpy(newPtr->title, title); 
        strcpy(newPtr->author, author);        
        newPtr->nextPtr = NULL;

        BookPtr previousPtr = NULL;
        BookPtr currentPtr = *listPtr;

        while (currentPtr != NULL && strcmp(author, currentPtr->author) > 0) {            
            previousPtr = currentPtr;
            currentPtr = currentPtr->nextPtr;
        }
        if (previousPtr == NULL) { //empty list
            newPtr->nextPtr = *listPtr;            
            *listPtr = newPtr;        
        } else {
            while (currentPtr != NULL && strcmp(title, currentPtr->title) > 0 && !(strcmp(author, currentPtr->author))) {            
                previousPtr = currentPtr;
                currentPtr = currentPtr->nextPtr;
            }
            if(!(strcmp(previousPtr->isbn, newPtr->isbn))) { //this is the part that doesn't work. it should check if the new book and the one in the position where i would insert it have the same isbn code
                currentPtr->totCopies = (currentPtr->totCopies) + 1;
            } else {  
                previousPtr->nextPtr = newPtr;
                newPtr->nextPtr = currentPtr;
            }    
        }    
    }
    else {
        puts("Error");    
    }
}

int main() {
    Book l;
    Book *listPtr = NULL;

    l = getBook();

    while(strcmp(l.isbn, "0")) { 
        insertBook(&listPtr, l.isbn, l.title, l.author);
        l = getBook();
    }
    return 0;
}

有任何想法吗?

标签: clist

解决方案


推荐阅读