【问题标题】:Remove/Destroy Function logic (Struct/Tries)删除/销毁函数逻辑(结构/尝试)
【发布时间】:2016-04-13 16:34:36
【问题描述】:

我一直在编写一个 Trie 程序以进行练习,但在尝试创建一种删除或销毁当前在 trie 中的单词的方法时,我遇到了一些逻辑/编码问题:

#include "trie.h"
/**************************************************************************/
/* Helper Functions
 * trie_node_t * trie_new(  void );
 *         Allocates memory for a new trie node
 *         Returns NULL if memory allocation was not possible or
 *         a memory address to a trie_node in the heap
/**************************************************************************/
trie_node_t * trie_new(  void ){
    trie_node_t * tmp = NULL;
    int i;
    if ( ( tmp = ( trie_node_t * ) malloc ( sizeof( trie_node_t ) ) ) == NULL )
    return NULL;
    for( i = 0; i < ALPHA_SIZE; i++ ) { 
        tmp->child[ i ] = NULL;
        tmp->end = 1;
    }
return tmp;
}
/**************************************************************************/
/* Functions functions       
 * int trie_size     ( trie_node_t *  root );
 *         Returns the number of words in the trie
 * int trie_contains ( trie_node_t *  root,    char word[ ] );
 *         Returns 1 if a the word is in the trie
 *                 0 otherwise
 * int trie_insert   ( trie_node_t ** rootRef, char word[ ] );
 *         Returns 1 if the word is inserted in the trie
 *                 0 otherwise
 * int trie_remove  ( trie_node_t ** rootRef, char word[ ] );
 *         Returns 1 if the word is removed from the trie
 *                 0 otherwise
 * int trie_destroy  ( trie_node_t ** Tref );
 *         Returns 1 if the trie and all its node are destroyed
 **************************************************************************/
int trie_size     ( trie_node_t *  root ) {
    int i = 0;
    int count = 0;
    trie_node_t *temp = root; //Creates a temp variable (Because its being modified)
    //if the reference does not exist(no more children)
    if (temp == NULL){
    return EXIT_FAILURE;
}
//loops through the child array
for (i = 0; i < ALPHA_SIZE; i++){
    //if the reference to next child is not null
    if(temp->child[i] != NULL){
        //and the end character is '/0' (or not)
        if(temp->child[i]->end == '/0'){
            count += 1;
        }
        //add the return of trie_size to count, then run through the method again at the lower level.
        count += trie_size(temp->child[i]);
    }
}
return count;
}
/**************************************************************************/
int trie_contains ( trie_node_t *  root,    char word[ ] ){
trie_node_t *temp = root; //Create a temp variable, can't use the default root. (just a location).
int i = 0;
int length = strlen(word); //finds the length of array
int index = 0;
if (temp ==  NULL){
    return EXIT_FAILURE;
}
if(!valid_word(word)){
    return 0;
}
for (i = 0; i < length; i++){
    index = charToInt(tlower(word[i]));
    if (!temp->child[index]){
        return 0;
    }
    temp = temp->child[index];
}
if (temp->end != '/0'){ //Checks if the end character at the last index is '/0' if it is not, it is not a word. Return 0 (not found)
    return 0;
}
return 1;
}
/**************************************************************************/
int trie_insert   ( trie_node_t ** rootRef, char word[ ] ){
trie_node_t *temp = *rootRef; //Create a temp variable, can't use the default rootRef. (just a location).
int i = 0;
int length = strlen(word); //finds the length of array
int index = 0;
if (temp == NULL){ //checks that the reference is not null
    return EXIT_FAILURE;
}
if (!valid_word(word)){//checks if word is valid.
    return 0;
}
for (i = 0; i < length; i++){
    if (word[i] == '/0'){
        index = 26;
    } else if (word[i] >= 'A' || word[i] <= 'Z'){
        index = charToInt(tolower(word[i])); //turns the word[i] into a usable integer.
    }
    else {
        return EXIT_FAILURE;
    }
    if (!temp->child[index]){ //if there is not a child reference.
        temp->child[index] = trie_new(); //create one.
    }
    temp = temp->child[index]; //move down to next level (next child)
}
temp->end = '\0';
return 1;
}
/**************************************************************************
* I'm pretty sure the majority of this method is incorrect, this was just an attempt I had. From what I understand I have to do is this:
* (1) Find the last character in the word (Found with the '/0' end char) and as long as there are no nodes connected at a lower level free the memory.
* (2) Move up (recursion is probably the easiest way to do this, but I haven't been able to figure out how) and check again. 
* (3) Continue until the first letter of the word is reached, then exit.
* My question is how do I check to see if another node is connected? Also what would be the format of the recursive call?
**************************************************************************/
void trie_remove  ( trie_node_t ** rootRef, char word[ ] ){
trie_node_t *temp = *rootRef;
int i = 0;
int index = 0;
int length = strlen(word);
if (temp == NULL){
    return;
}
if (!valid_word(word)){
    return;
}
//Code is incomplete, just an attempt.
for (i = 0; i < length; i++){
    index = charToInt(tolower(word[i])); //not sure if this is necessary.
    if (temp->child[i]->end == '/0'){
        free(temp->child[i]);
    } 

}
return;
}
/**************************************************************************/
int trie_destroy  ( trie_node_t ** rootRef ){

//issues with logic here, not exactly sure how to do this.

return 1;
}
/**************************************************************************/
int trie_init(trie_node_t **rootRef){
if ( *rootRef ==  NULL) {
    *rootRef = trie_new();
}
return 1;
}
/**************************************************************************/
int valid_word (char word[]){
int length = 0;
int i = 0;
for (i = 0; i < length; i++){
    if(charToInt(word[i]) > 26 || charToInt(word[i]) < 0){
        return 0;
    }
}
return 1;
}
/**************************************************************************/
int charToInt(char c){
return (int)c-(int)'a';
}

Trie.h:(无论如何都很重要)ALPHA_SIZE 是 27。

typedef struct trie_node {
    char end;
    struct trie_node *child[ ALPHA_SIZE ]; //reference to trie node.
}trie_node_t;

我希望我正确地格式化了这个问题,并且我已经在网站上查看了可能的解决方案,但还没有找到任何解决方案。如果有人可以帮助我检查我的逻辑/帮助我编写这些方法的编码,那就太棒了。我不只是想要我想了解它为什么工作的代码!

提前致谢。

【问题讨论】:

  • 不清楚逻辑/编码问题是什么。它们是什么??
  • 我在 trie.c 中的删除和销毁函数的逻辑/编码方面遇到问题。

标签: c struct logic trie


【解决方案1】:

对于 Remove,您需要从 trie 中删除 free'd 指针:

for (i = 0; i < length; i++){
    index = charToInt(tolower(word[i])); //not sure if this is necessary.
    if (temp->child[i]->end == '/0'){
        free(temp->child[i]);
        temp->child[i]=0;  // lets not point to free'd elements
    }
}

对于销毁 - 大致尝试递归:

for (int i=ALPHA_MIN; i < ALPHA_MAX; ++i)
{
    if (rootRef->child[i])
    {
         trie_destroy(rootRef->child[i]);
    }
}

free (rootRef);

【讨论】:

  • 谢谢你,这对我帮助很大!
猜你喜欢
  • 1970-01-01
  • 2014-02-17
  • 1970-01-01
  • 1970-01-01
  • 2020-12-27
  • 2016-02-28
  • 1970-01-01
  • 2019-09-07
  • 1970-01-01
相关资源
最近更新 更多