将属性数据推送到trie,添加到多个键

时间:2014-04-14 22:10:24

标签: c++ recursion trie

我的知识有限,但我一直在这个特定的数据结构上工作(黑客)

我使用trie来存储本体字符串,然后将其作为堆栈返回,包括“#gap;'调用get(string)时的接近程度。作为关键字上的trie store属性的添加。字符串越靠后,属性的细节越多。这对我的目的很有用。

作为附加添加,我使用通配符将属性应用于所有子节点。例如,添加'爪子'对于哺乳动物的所有子节点。'我推(哺乳动物。狗。*。爪子)。现在,所有的狗都有爪子。

问题只是第一只狗得到了爪子。该函数适用于没有Wild

的推送属性

如果你想我可以清理它并提供简化版本,但过去我在stackoverflow上发现最好只提供代码;我使用' z'作为' *'野生

void Trie::push(ParseT & packet)
{
    if (root==NULL) AddFirstNode(); // condition 1: no nodes exist, should this be in wrapper
    const string codeSoFar=packet.ID;
    AddRecord(root, packet, codeSoFar); //condotion 2: nodes exist
}

void Trie::AddFirstNode(){ // run-once, initial condition of first node
    nodeT *tempNode=new nodeT;
    tempNode->attributes.planType=0;
    tempNode->attributes.begin = 0;
    tempNode->attributes.end = 0;
    tempNode->attributes.alt_end = 0;
    root=tempNode;
}



//add record to trie with mutal recursion through InsertNode
//record is entered to trie one char at a time, char is removed
//from record and function repeats until record is Null
void Trie::AddRecord(nodeT *w, ParseT &packet, string codeSoFar)
{
    if (codeSoFar.empty()) {

        //copy predecessor vector at level n, overwrites higher level vectors
        if (!packet.predecessorTemp.empty())
            w->attributes.predecessorTemp = packet.predecessorTemp;

        return;  //condition 0: record's last char
    }
    else { //keep parsing down record path

        for (unsigned int i = 0; i < w->alpha.size(); i++) {
            if (codeSoFar[0] == w->alpha[i].token_char || codeSoFar[0] == 'z') {
                return AddRecord(w->alpha[i].next, packet, codeSoFar.substr(1)); // condition 2: char exists
            }
        }
        InsertNode(w, packet, codeSoFar); //condition 3: no existing char --> mutal recursion
    }
}

//AddRecord() helper function
void Trie::InsertNode(nodeT *w, ParseT &packet, string codeSoFar) // add new char to vector array
{
    for (unsigned int i=0; i <=w->alpha.size(); i++) { // loop and insert tokens in sorted vector
        if (i==w->alpha.size() || codeSoFar[0] < w->alpha[i].token_char) { //look for end of vector or indexical position

            //create new TokenT
            tokenT *tempChar=new tokenT;
            tempChar->next=NULL;
            tempChar->token_char=codeSoFar[0];

            //create new nodeT
            nodeT *tempLeaf=new nodeT;
            tempLeaf->attributes.begin = 0;
            tempLeaf->attributes.end = 0;
            tempLeaf->attributes.planType = 0;
            tempLeaf->attributes.alt_end = 0;

            //last node
            if (codeSoFar.size() == 1){

                tempLeaf->attributes.predecessorTemp = packet.predecessorTemp;
            }

            //link TokenT with its nodeT
            tempChar->next=tempLeaf;
            AddRecord(tempLeaf, packet, codeSoFar.substr(1)); //mutual recursion --> add next char in record, if last char AddRecord will terminate

            w->alpha.insert(w->alpha.begin()+i, *tempChar); 
            return; 
        }
    }
}

root is global nodeT *w

    struct ParseT {

        string ID; //XML key

        int begin = 0; //planned or actual start date
        int end = 0; //planned or actual end date - if end is empty then assumed started but not compelted and flag with 9999 and 
        int alt_end = 0; //in case of started without completion 9999 case, then this holds expected end
        int planType = 0; //actuals == 1, forecast == 2, planned == 3

        map<string, string> aux;

        vector<string> resourceTemp;
        vector<string> predecessorTemp;
    };

This is what I'd like it to do

1 个答案:

答案 0 :(得分:1)

在此代码中

    for (unsigned int i = 0; i < w->alpha.size(); i++) {
        if (codeSoFar[0] == w->alpha[i].token_char || codeSoFar[0] == 'z') {
            return AddRecord(w->alpha[i].next, packet, codeSoFar.substr(1)); // condition 2: char exists
        }
    }

一旦拨打AddRecord,即使是因为通配符,您也会返回。当codeSoFar[0] == 'z'遍历所有alpha并添加记录时,可能更容易有一个单独的循环。然后有一个else子句来执行当前代码。

编辑:这就是我的意思,代码形式:

else { //keep parsing down record path
    // Handle wildcards
    if (codeSoFar[0] == 'z') {
        for (unsigned int i = 0; i < w->alpha.size(); i++) {
            AddRecord(w->alpha[i].next, packet, codeSoFar.substr(1)); // condition 2: char exists
        }
    }
    else {
        // Not a wildcard, look for a match
        for (unsigned int i = 0; i < w->alpha.size(); i++) {
            if (codeSoFar[0] == w->alpha[i].token_char) {
                return AddRecord(w->alpha[i].next, packet, codeSoFar.substr(1)); // condition 2: char exists
            }
        }
        InsertNode(w, packet, codeSoFar); //condition 3: no existing char --> mutal recursion
    }
}