C语言 从字符串链列表中删除字符串



我正在开发一个文字处理器,要求能够从单词列表中删除一个单词。

基本上,用户输入单词(因此,字符串(,然后将其存储在链表中(此处为dico,这要归功于表示用户输入的所有单词的结构字典(。

不幸的是,我被卡住了:似乎我编写的代码只删除了第二个字符,而我希望它能够删除用户请求的单词(此处:str(。

例如,如果用户之前输入了:"hello world",现在他们想要删除世界"world",那么dco现在应该是"hello"。

typedef struct dll {
char data;
int count;      //not needed here
struct dll* next;
} dll;  //linked list of each character : dll represents one word
typedef struct dictionary {
dll * data;
struct dictionary* next;
struct dictionary* prev;
} dictionary;  //linked list of all the words
dll* entry(){
char data = getc(stdin);
if (data != 'n'){
dll* curr = create_dico(data);
curr->next=entry();
return curr;
}
return NULL;
}

void suppression(dictionary** dico) {
printf("Please enter what you wish to remove out of the list: n");
dictionary *str = malloc(sizeof(dictionary));
str->data = entry();
str->next = NULL;
dictionary* temp = *dico;
if (str->data == NULL){
*dico = temp->next;
free(temp);
return;
}
while (temp != NULL && temp->data->data == str->data->data) {
temp = temp->next;
}
dictionary *next = temp->next->next;
free(temp->next);
temp->next = next;
}

您的删除函数不会反映您正在使用的数据结构:链表的链表!

您需要做的第一件事是检测单词的位置,您需要为此目的比较两个链表:

// notice: pointer to dll, not dictionary!
dll* str = entry();
dictionary* temp = *dico;
while(temp)
{
dll* s = str; // you yet need original str for deletion!
dll* word = temp->data;
while(word && s && word->data == s->data)
{
word = word->next;
s = s->next;
}
// OK, now we need to know if we reached the ends of BOTH word and s
// -> in that case, both are equal!
if(!word && !s)
break;
}

所以我们现在迭代了单词列表。如果我们在里面找到字符串,我们会过早地停止,否则我们会在最后到达空元素。所以:

if(temp)
{
// we didn't reach end of the words' list -> we found an equal element
// at first, we'd remove the current word from the linked simply by
// re-linking predecessor and successor nodes
// the nice thing about is that you created a doubly linked list
// so we have both of them available from current node, so:
if(temp->prev)
temp->prev->next = temp->next;
else
// special case: we are deleting the head node!
*dico = temp->next;
if(temp->next)
temp->next->prev = temp->prev;
// no else needed, as we haven't a dedicated tail node
// now we need to delete the word's characters!
dll* word = temp->data;
while(word)
{
dll* next = word->next;
free(word);
word = next;
}
// now we yet need to delete the word node itself!
free(temp);
}

到目前为止很好,列表已调整。但是,我们创建了一个临时引用字符串,它本身也需要再次释放:

while(str)
// well, just the same as when deleting the word...

当您两次执行相同的操作时,您可能会为...

请注意,以上是未经测试的代码,不能保证它没有错误。但它应该足以显示您必须关注的地方......还要注意,这个答案是基于相当多的假设,主要是之前正确创建的列表,因为你没有提供一个最小的可重现示例。

相关内容

  • 没有找到相关文章

最新更新