【问题标题】:Prefix tree implementation前缀树实现
【发布时间】:2017-02-16 06:23:31
【问题描述】:

我正在存储城市列表(从文件中读取)及其相应的纬度和经度值。在每个城市的末尾,我都在尝试附加经度和纬度值。

例如,特里里的弗里蒙特看起来像

F->R->E->M->O->N->T->(经纬度)

我能够成功地将值插入到 trie 中,但是当我尝试搜索特定城市时,经度和纬度值返回为 (null)

这是我的实现

void readFile(){

              //the functions that deal with the trie
                struct trieNode *node = initializeTrie();
                trieInsert(node, place, longitude, latitude);
                getTrie(node, place);
                trieFree(node);
}

struct trieNode{
        char *longi;
        char *lat;
        struct trieNode *children[27];
        char value;
};

struct trieNode *initializeTrie(){
        struct trieNode *pNode = NULL;

        pNode = (struct trieNode *)malloc(sizeof(struct trieNode));
        if(pNode){
                pNode->longi = '\0';
                pNode->lat = '\0';
                pNode->value = '\0';
                memset(pNode->children, 0, sizeof(pNode->children));
        }

        return pNode;
}


void trieFree(struct trieNode *root){
        int i;
        if(root){
                for(i = 0; i<= 26; i++){
                        trieFree(root->children[i]);
                }
        }
        free(root);
}

int trieInsert(struct trieNode *node, char *key, char *longitude, char *latitude){
        struct trieNode *parent = node;
        //printf("Longi: %s", longitude);
        //printf(" ");
        //printf("Latitude: %s \n", latitude);
        if(key){
                int index = 0;
                int i = 0;

                if(node){
                        while(key[i] != '\0'){
                                int indexVal = convertLetterToIndex(key[i]);
                                if(!parent->children[indexVal]){
                                        parent->children[indexVal] = initializeTrie();
                                        parent->children[indexVal]->value = key[i];
                                }
                                parent = parent->children[indexVal];
                                i++;
                        }

                        int longitudeLen = strlen(longitude);
                        int latitudeLen = strlen(latitude);

                        node->longi = malloc(longitudeLen + 1);
                        strncpy(node->longi, longitude, longitudeLen + 1);
                        node->longi[longitudeLen] = '\0';
                        //printf("Longi: %s", node->longi);
                        node->lat = malloc(latitudeLen + 1);
                        strncpy(node->lat, latitude, latitudeLen + 1);
                        node->lat[latitudeLen] = '\0';
                        //printf("Lati: %s \n", node->lat);
                        //free(node->longi);
                        //free(node->lat);
                }
        }


}

 //function to print the long and lat values based on the city
void getTrie(struct trieNode *root, char *key){
        struct trieNode *pNode = root;
        //bool flag = false;
        if(!key){
            printf("Not found \n");
        }

        if(!root){
                printf("Not found \n");
        }
        int i = 0;
        while(key[i] != '\0'){
                int indexVal = convertLetterToIndex(key[i]);
                if(!pNode->children[indexVal]){
                        printf("Not found \n");
                }

                pNode = pNode->children[indexVal];
                i++;
        }

        printf("Longitude: %s", pNode->longi);
        printf(" ");
        printf("Latitude: %s \n", pNode->lat);


}

【问题讨论】:

  • 我没有看到任何明显的问题会导致您描述的行为。我认为MCVE 会有所帮助。另外,看看How to debug
  • 其他几个问题:pNode-&gt;longi = '\0';初始化不是空字符串,而是将longi初始化为NULL,基本上是“根本没有字符串”。在出现“未找到”错误后,您在 getTrie 中没有 returns。
  • @yeputons 但我在 getTrie 函数中有打印语句
  • 你做了,但是它们后面没有return,所以继续执行,这会导致未定义的行为,因为你的代码可能从空指针读取。
  • @yeputons 我将该函数留作空,您还提到 pNode->longi = '\0' 不正确,它也应该初始化什么

标签: c prefix-tree


【解决方案1】:

首先longilat的类型是char *,而不是char作为value,所以初始化

   pNode->longi = '\0';
   pNode->lat = '\0';
   pNode->value = '\0';

看起来不太对。

应该是这样的

   pNode->longi = NULL;
   pNode->lat = NULL;
   pNode->value = '\0';

(我不想问为什么value只有一个字符——它是一种特殊的数据表示方式)

接下来要注意的是使用strncpystrlen 函数。

当您使用trieInsert 函数接收指向char 的指针时,您应该在使用strlen(longitude)strncpy(node-&gt;longi, longitude, longitudeLen + 1) 等表达式之前检查它们是否为if(longitude != NULL)。当然,指针的逻辑必须是这样的:

  • 定义指针并用NULL初始化;

  • 使用malloc或任何其他函数分配内存(如果分配失败,C标准动态内存分配函数返回空指针);

  • 检查指针的值,在if( p != NULL)if( p )之后使用。

这是一种很好的做法。

【讨论】:

  • 所以最后一位是为了良好的编码风格,只是想确保该位是否没有任何错误,因为我能够打印出 node->longi 和 node 的值->纬度。这告诉我这些值正在填充到 trie
猜你喜欢
  • 2011-09-14
  • 2010-12-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-19
  • 1970-01-01
  • 2016-02-15
  • 2012-02-18
相关资源
最近更新 更多