【问题标题】:Storing elements of a string on a Linked List [closed]将字符串的元素存储在链接列表中[关闭]
【发布时间】:2014-01-03 03:29:01
【问题描述】:

我的链接列表有一个小问题。 我用字符串构建了一个链表,它工作得很好。 现在因为我使用 strtok() 来分隔字符串,所以我需要帮助来单独存储结构但保持它们连接。 希望我解释清楚

现在这就是我所拥有的:

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


 typedef struct dict_word *word;
 typedef struct node *Node;
 typedef struct double_linked_list *DLL;




 struct dict_word
 {
char words[100];
int year[10];
char eng_synonyms[100];
char heb_synonyms[100];
 };


 struct node
 {
word data;
Node *next;
Node *previous;
 };


 struct double_linked_list
 {
Node *head;
Node *last;
 };


 char *split(char words[100])
 {
int i;
char *word=strtok(words, "_#_");
char *year=strtok(NULL, "_#_");;  // assigning NULL for previousely where it left off
char *definition=strtok(NULL,"_#_");
char *synonyms=strtok(NULL,"_#_");

i=atoi(year);

printf("%s\n", word);
printf("%i\n",i);
printf("%s\n", definition);
printf("%s\n", synonyms);
return 0;
 }

这是我通过只有一个字符串插入节点的功能:

 void insert_beginning(char words[99])
 {
struct node *var, *temp;
var=(struct node *)malloc(sizeof(struct node)); //explination about the (node *)
strncpy(var->data, words,99);

if (head==NULL)
{
    head=var;
    head->previous=NULL;
    head->next=NULL;
    last=head;
}
else
{
    temp=var;
    temp->previous=NULL;
    temp->next=head;
    head->previous=temp;
    head=temp;
}
 }

【问题讨论】:

  • 因为你有很多字符串要存储,建议为你的结构创建那么多 char* .. 不过需要一些关于你的问题的解释
  • 我需要建立一个双链表来存储像这样的字符串:love_#_1986_#_affection_#_ADORE 基本上我需要一个函数来存储每个单词但保持它们之间的连接。就像我需要搜索 ADORE 一样,输出应该是 Found ADORE in the word love
  • 我解释清楚了吗?

标签: c string linked-list


【解决方案1】:

在 2014 年看到用于处理此类抽象数据的纯 C 代码,我有点惊讶。

不过,我认为您应该将实际的图书数据与列表分开。

strtok 将修改您的初始字符串(在每个标记的末尾插入“\0”)。如果要访问strtok 将字符串拆分成的各个位,则必须记住所有指向标记的指针(单词、定义等)。

所以你应该创建一个结构来将所有这些结合在一起:

typedef struct {
    const char * words;
    int          year;
    const char * definition;
    const char * synonyms;
} dict_word;

现在要创建一条新记录,您必须复制各种标记,就像您之前在链接列表插入中所做的那样。

但是这次复制会更快发生,使用strdup函数。

dict_word * create_record (char * raw) // raw record string
{
    // allocate a new object
    dict_word record = (dict_word *) malloc (sizeof (record));
    assert (record != NULL);

    /*
     * sanity checks left out for concision,
     * but you should make sure your input is properly formatted
     */

    // populate the fields
    record->word       = strdup (strtok(raw , "_#_"));
    record->year       = atoi   (strtok(NULL, "_#_"));
    record->definition = strdup (strtok(NULL, "_#_"));
    record->synomyms   = strdup (strtok(NULL, "_#_")); 

    // done
    return record;  
}

您将需要一个清理函数来释放记录创建期间分配的所有内存:

void delete_record (record * r)
{
    // first free all strings
    free (r->word);
    free (r->definition);
    free (r->synomyms);

    // then free the object
    free (r);
}

现在是列表。

您可以将列表定义为更独立的对象,而不是将处理列表的代码与关心书籍的代码混为一谈:

typedef struct sNode {
    struct sNode * next;
    struct sNode * prev;
    void *         data; // this will point to the linked objects
} listNode;

typedef struct
{
    listNode *head;
    listNode *tail; // either first/last or head/tail, but keep it consistent :)
} List;

首先你需要初始化列表:

void List_init (List * l)
{
    l->head = l->tail = NULL;
}

然后你会想要给它添加元素

void List_put (List * list, void * data)
{
    // allocate a node
    listNode * node = (listNode *) malloc (sizeof (node));
    assert (node != NULL);

    // store data reference
    node->data = data;

    // insert the node at the end of list
    node->prev = list->tail;
    node->next = NULL;
    list->tail = node;
    if (list->head == NULL) list->head = node;
}

最后,要使用所有这些:

// create the list
List book_list;
List_init (&book_list);

/* ... */

// create the records
char * raw_record;
while ((raw_record = read_from_database ()) != DONE_READING)
{
    List_put (book_list, create_record (raw_record));
}

/* ... */

// browse the records
listNode * node;
for (node = book_list->head; node != NULL; node = node->next)
{
    dict_word * record = (dict_node *) node->data;

    // do whatever you want with your record
}

说了这么多,C 充其量也不足以处理这种高级数据。

从 C++ 开始,您可以用各种更现代的语言编写非常更紧凑、更可靠和更高效的等价物。

现在,如果您只是一个学生,被教授的老家伙要求做一些尘土飞扬的 C 作业,并希望 StackOverflow 贡献者的老家伙为您完成它,那么……今天是您的幸运日.

【讨论】:

  • 大声笑哇非常感谢你,即使我是一名学生,我也很感激,但我意识到,如果只是一个家庭作业,最好学习如何去做,我真的很感激。我会再看一遍并理解这一切谢谢你
  • 我的荣幸。我曾经也是一名学生,但当时(在法国巴黎这样偏远的地方)没有互联网这样的东西 :) 而且所有这些代码都在我脑海中,所以不要指望它开箱即用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-10-20
  • 2020-09-08
  • 1970-01-01
  • 1970-01-01
  • 2021-12-16
  • 2022-01-20
  • 1970-01-01
相关资源
最近更新 更多