通过子字符串搜索链接列表,并使用包含子字符串的所有结构创建新的链接列表

时间:2016-10-24 01:41:33

标签: c string linked-list

假设我有以下结构:

struct _node {
    int id;
    char *name;
    struct node *next;
};

我想编写一个遍历链表的函数,并查找名称成员包含某个子字符串的结构,并将这些结构添加到新的链表中并返回新的链表。

我尝试使用strstr这样做,但在某些时候我得到一个无限循环,我无法弄清楚无限循环发生的确切原因。

这是我的功能:

struct _node *containSubstr(struct _node *head, char needle[]) {
    if (head == NULL) {
        printf("BLOOP BLEEP BOOP BEEP.\n");
        exit(EXIT_FAILURE);
    }

    struct _node *curr = head;
    struct _node *returnHead = createEmptyNode();

    while (curr != NULL) {
        char haystack[strlen(curr->name)];
        strcpy(haystack, curr->name);

        strToLower(needle);
        strToLower(haystack);

        if (strstr(haystack, needle) != NULL) {
            // this is where I get the infinite loop
            append(returnHead, curr);
        }

        curr = curr->next;
    }

    return returnHead;
}

函数append和createEmptyNode经过测试并正常工作。

我多次查看逻辑,我认为这必须有效。我用print语句填充了我的代码,似乎在找到包含子字符串的所有节点后,它不断重复最后一个节点并进入无限循环。

这是我的追加功能:

void append(struct _node *head, struct _node *newNode) {
    if (head == NULL) {
        printf("BLOOP BLEEP BOOP BEEP.\n");
        exit(EXIT_FAILURE);
    }

    struct _node *curr = head;

    if(curr == NULL) {
        head = newNode;
    }
    else {
        while(curr->next != NULL) {
            curr = curr->next;
        }
        curr->next = newNode;
    }
}

1 个答案:

答案 0 :(得分:1)

想象一下这种情况:你有一个列表 L ,它只包含链表中的2个节点( A B )。想象一下,节点 A B 都包含您要查找的子字符串:

原始列表 L

A-> B-> NULL

因此,在第一次迭代后,您的新列表 L2 应如下所示:

A-> NULL

但是在您的追加功能中,您不会创建新节点的深层副本。因此,您的新列表 L2 如下所示:

Empty_node-> A-> B-> NULL

在下一步中,您将移至节点 B 。所以你拿 L2 并在那里附加 B 。第二次迭代后,您的 L2 如下所示:

Empty_node-> A-> B-> B(B指向自身)。

由于您没有创建深层副本,因此您实际上始终使用列表 L ,并且当您将节点 B 附加到您认为的列表 L2时您实际上将 B 附加到 L ,然后 B 指向自己curr->next = newNode; append功能)。因此,在下一次迭代中,您再次询问 B 是否包含您要查找的字符串。

<强>结论

创建新列表时需要创建深层副本。

在当前设置中,append功能会修改原始列表。