c - 尝试在插入过程中消除列表中的重复项
问题描述
我正在编写一个 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;
}
有任何想法吗?
解决方案
推荐阅读
- linux - 选择哪个 yocto 发布标签
- python - 提取 .docx 数据、图像和结构
- python - 字体根据不同的语言变化?
- reactjs - 如何抑制 Typescript CSSProperties 错误
- python - Keras 的 Conv1d 中的 input_shape 变量是如何工作的?
- sparql - 如何查询owl:equivalentclass的隐式属性
- python - 获取数组中按钮的索引(按下时)
- git - Git 分支创建和删除历史
- java - 如何为仅显示具有相同值的数组的多个列表创建条件
- python - 将 datetime.datetime 转换为星期几,然后绘图