write trie parsing recursive function with node st

2019-08-31 09:25发布

The purpose: This function parses through a string trie following the path that matches an input string of characters. When all the char in the string are parsed, true is returned. I want to step over a char and return if there is still a valid path.

The application: the strings are a location hierarchy for a highway project. So, project 5 has an alignment C, that has an offset of N and a workzone 3; 5CN3. But, sometimes I want to define a string for all child locations for a project task that covers all the locations. So, '0' is all locations; for a half day operation like grade dirt has no workzones - all the so to represent this task is all workzones in the north alignment C; 5CN0. same for if an operation covers the whole project; 5000.

Approaches: I could have used a wildcard '?' function but I want to keep this specific step over for the purpose of abstracting the locations. Maybe '?' is the right approach, but seems to loose some control. Also, this could be written without the for loop and use a position index parameter; maybe that is where this goes wrong - maybe on backtracking.

Code: nodeT is the trie nodes, word is the input string, this function is a bool and returns 1/0 if the string path exists.

bool Lexicon::containsWordHelper(nodeT *w, string word)) //check if prefix can be combined
{
    if(word == "") { //base case: all char found
        return true;
    } else {
        for(int i = 0; i < w->alpha.size(); i++) { //Loop through all of the children of the current node
            if (w->alpha[i].letter == word[0])
                return containsWordHelper(w->alpha[i].next, word.substr(1));
            else if (word[0] == '0') //if '0' then step over and continue searching for valid path
                containsWordHelper(w->alpha[i].next, word.substr(1)); //removed return here to allow looping through all the possible paths
        } //I think it is continuing through after the loop and triggering return false
    }
    return false; //if char is missing - meaning the exact code is not there
}

The problem is that this returns false when a '0' wildcard is used. What is going wrong here? My knowledge is limited.

I hacked on this problem for awhile and used the 'howboutthis howboutthat' approach, and found that placing the return at the end of the step over statement works.

bool Lexicon::containsWordHelper(nodeT *w, string word, int &time, int &wag, string compare) //check if prefix can be combined
{
    if(word == "") { //base case: all letters found
        if ((w->begin-wag) <= time && time <= (w->end+wag)) 
            return w->isWord; // case 2: timecard check for high/low date range
        else if (time == ConvertDateToEpoch(9999, 01, 01)) return w->isWord; //this is for single code lookup w/o date
    } else {
        for(int i = 0; i < w->alpha.size(); i++) { //Loop through all of the children of the current node
            if (w->alpha[i].letter == word[0])
                return containsWordHelper(w->alpha[i].next, word.substr(1), time, wag, compare);
            else if (word[0] == 'ž')
                if (containsWordHelper(w->alpha[i].next, word.substr(1), time, wag, compare)) return true;
        }
    }
    return false; //if char is missing - meaning the exact code is not there
}

It seems logical that if I only one the path that ends in true to return then I should place the return after the recursion is done and then conditionally pass back only if true. It works and seems logical in retrospect, but my confidence in this is sketchy at best.

I still have the same question. What is/was going wrong?

2条回答
Animai°情兽
2楼-- · 2019-08-31 09:44

You could test the result of the latter containsWordHelper call and return true if the result is true, else continue iterating.

查看更多
闹够了就滚
3楼-- · 2019-08-31 09:47

Solved: place a return after an if statement containing the recursive call

bool Lexicon::containsWordHelper(nodeT *w, string word) 
    {
        if(word == "") return w->isWord;
        else {
            for(int i = 0; i < w->alpha.size(); i++) {
                if (w->alpha[i].letter == word[0])
                    return containsWordHelper(w->alpha[i].next, word.substr(1));
                else if (word[0] == 'ž')
                    if (containsWordHelper(w->alpha[i].next, word.substr(1))) return true;
            }
        }
        return false;
    }
查看更多
登录 后发表回答