c - 在 C 中重建索引

标签 c data-structures strtok

我有一个程序以这种格式读取一个巨大的行文本文件,我需要从这个文本文件构建一个数据结构。

microfinance 5 41 5 1650 2 1667 1 1811 1 1988 5 
subminiature 1 432 1 

单词后的第一个数字是找到该单词的文档数。以下数字在文档 ID 号和文档中找到的单词出现次数之间交替出现。所以对于小额信贷,有 5 个文档,第一个是文档 41,出现了 5 次,接下来是文档 1650,出现了 2 次,依此类推。

我使用 strtok 获取每个元素并组织它们。我知道 strtok 工作正常。问题是将元素正确附加到我的数据结构。

DocumentNode *myDoc;
while (fgets(theLine, sizeof(theLine), newPointer) != NULL)
    {
        counter = 0;
        pch = strtok (theLine," ");
        while (pch != NULL)
        {
         if (0 == counter)
         {
            WordNode *toInsertPtr = (malloc(sizeof(struct WordNode)));
            word = (malloc(100));
            strncpy (word, pch, strlen(pch));
            toInsertPtr->word = word;
            toInsertPtr->next = NULL;

            currIndex = JenkinsHash(word, MAX_HASH_SLOT);
            if ((TheIndex->index[currIndex]) == NULL)
            {
                TheIndex->index[currIndex] = toInsertPtr;
            }
            else 
            {
                TheIndex->index[currIndex]->next = toInsertPtr;
            }   
         }

         if (1 == counter)
         {
            numOfDocs = atoi(pch);
         }

         if (counter % 2 == 0 && counter != 0 && pch != NULL)
         {
            myDoc= (malloc(sizeof(struct DocumentNode)));
            myDoc->next = NULL;
            int doc_id = atoi(pch);
            myDoc->documentID = doc_id;         
         }

         if (counter % 2 != 0 && counter != 1 && pch != NULL)
         {
            myDoc->occurences = atoi(pch);

            if (TheIndex->index[currIndex]->page == NULL)
            {
                TheIndex->index[currIndex]->page = myDoc;
            }
            else
            {
                TheIndex->index[currIndex]->page->next = myDoc;
            }
         }
          pch = strtok (NULL, " ");
          counter++;
        }
    } 

我已经 GDBed 发现问题出在这里。第一个 if 语句检查索引处是否有 doc 节点总是捕获为 null(即使索引中的那个点明显有东西)并且它一次又一次地覆盖一个槽。为什么它总是认为它不是 NULL?

        if (TheIndex->index[currIndex]->page == NULL)
        {
            TheIndex->index[currIndex]->page = myDoc;
        }
        else
        {
            TheIndex->index[currIndex]->page->next = myDoc;
        }

数据结构如下:

typedef struct DocumentNode {
    struct DocumentNode *next;      // pointer to next member of the list.
    int documentID;                 //doc identifier (filename, ie. 1, 2, etc.)
    int occurences;                 //num. occurances. 
} DocumentNode;

typedef struct WordNode {                
    struct WordNode *next;           //pointer to the next word (for collisions)
    char *word;                      //the word itself.
    DocumentNode *page;              // pointer to the first element of the page list.
} WordNode;

typedef struct InvertedIndex {
    WordNode *index[MAX_HASH_SLOT];   
} InvertedIndex;

最佳答案

您的方法太复杂:循环试图维持状态,并且有很长的条件链来决定如何处理下一个 token 。

与其一次一个地执行 strtok,不如执行第一个来获取单词,第二个来获取计数,然后将其余的成对执行。它应该如下所示:

while (fgets(theLine, sizeof(theLine), newPointer) != NULL) {
    pch = strtok (theLine," ");
    char *word = malloc(strlen(pch)+1);
    strcpy(word, pch);
    ... // Add the word
    pch = strtok(NULL, " ");
    int pairCount = atoi(pch);
    for (int i = 0 ; i != pairCount ; i++) {
         pch = strtok(NULL, " ");
         int id = atoi(pch);
         pch = strtok(NULL, " ");
         int count = atoi(pch);
         ... // Add the document
    }
}

附言如果你很好地理解这种方法,你可能会喜欢 this tale作者:Edsger Dijkstra。

关于c - 在 C 中重建索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30349925/

相关文章:

c - 如何在 gdb 中的 fork() 之后调试子进程?

java - 可以将一系列键映射到值的数据结构

java - 如何找到树中的第二大值

c - 如何将文件中的字符串和 float 存储到结构中?

c - 在 C 中标记化空白字符

c++ - 多次使用 strtok_s

c - 它会定义结构的结构吗?

C 缓冲区溢出预防

c - 当动态内存分配显式转换为结构类型时,到底会发生什么?

algorithm - NQueen真的在回溯吗?