简体   繁体   中英

Trie implementation runtime error

I'm trying to implement a Trie in C++ but I'm getting runtime error...

Here is my code:

#include <bits/stdc++.h>
using namespace std;

struct trie{
    bool word = false;
    trie* adj [26];
    trie(){}

    void add(char* s){
        trie* t = this;

        while(s){
            if(t->adj[s[0] - 'a'] == NULL){
                trie nova = create(s);
                t->adj[s[0] - 'a'] = &nova;
                return;
            }
            else{
                t = t->adj[s[0] - 'a'];
            }
            s++;
        }
    }

    trie create(char* s){
        trie t;
        trie* point = &t;
        while(s){
            point->adj[s[0] - 'a'] = new trie();
            point = point->adj[s[0] - 'a'];
            s++;
        }
        point->word = true;
        return t;
    }

    void seek(){
        trie* t = this;
        run(t, "");
    }

    void run(trie* t, string s){
        if(t->word){
            cout<<s<<"\n";
        }
        for(int i = 0; i < 26; i++){
            if(t->adj[i] != NULL){
                run(t->adj[i], s + char('a' + i));
            }
        }
    }
};

int main(){
    trie t;
    t.add("ball");
    t.add("balloon");
    t.add("cluster");
    t.seek();
}

It works like that:

  • suppose I'm adding a word;

  • if the letter of the word isn't in the trie

      if(t->adj[s[0] - 'a'] == NULL) 
    • make new trie with void create and set t->adj[s[0] - 'a'] to that new trie
  • else just go to the next letter and repeat the proccess

      t = t->adj[s[0] - 'a']; 

What am I doing wrong? I'm new at using pointers and I think I must have used one (or more) of them mistakenly... What is it wrong?

There are several problems which was found in your code.

  1. One problem resides in stack local variable trie nova being being deleted when it goes out of scope.

Code

...
if(t->adj[s[0] - 'a'] == NULL){
    trie nova = create(s);
    t->adj[s[0] - 'a'] = &nova; // address points to memory on stack
    return;
} // nova is deleted. t->adj[s[0] - 'a'] is pointing to trash now.
...

To handle it you should work with pointers and new operator.

...
if(t->adj[s[0] - 'a'] == NULL){
    trie* novaPtr = create(s + 1);
    t->adj[s[0] - 'a'] = novaPtr; 
    return;
} 
...

trie* create(char* s){
    trie *t = new trie();
    trie* point = t;
    while(*s){
        point->adj[s[0] - 'a'] = new trie(); // allocate memory on heap
        point = point->adj[s[0] - 'a'];
        s++;
    }
    point->word = true;
    return t; // the pointer on heap memeroy is returned.
}

  1. As @bkVnet noticed, you also should check for string termination in while loops all over the place. while(*s) - meaning while s is not pointing to '\\0' symbol instead of while(s) .

  1. You should initialize your adj pointers with NULL in struct constructor. Then it would be correct to check them for being NULL int he line if(t->adj[s[0] - 'a'] == NULL) .

Construct code.

trie() {
    for (int i = 0; i < 26; i++) adj[i] = NULL;
}

  1. There is a logical error in the line create(s); as one character should be taken away - create(s + 1) .

Full working code example

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM