bool matchTree(node* bigtree, node* smalltree) { if(smalltree==NULL && bigtree==NULL ) return 1; if(bigtree == NULL || smalltree==NULL) return 0; if(bigtree->data != smalltree->data) return 0; return matchTree(bigtree->left, smalltree->left) && matchTree(bigtree->right, smalltree->right); }
bool matchTree(TreeNode *r1, TreeNode *r2) { if (NULL == r1 && NULL == r2) { return true; } if (NULL == r1 || NULL == r2 || r1.data != r2.data) { return false; } return matchTree(r1.left, r2.left) && matchTree(r1.right, r2.right); }
bool matchTree(Node<T> *a, Node<T> *b) { if (!a && !b) return true; if (!a || !b) return false; if (a->data != b->data) return false; return matchTree(a->left, b->left) && matchTree(a->right, b->right); }
// check two tree with root as node1 and node2 are the same bool matchTree(treeNode *node1, treeNode *node2){ if(node1 == NULL && node2 == NULL){ return true; } else if(node1 == NULL || node2 == NULL){ return false; } else if(node1->data != node2->data){ return false; } else{ return matchTree(node1->left, node2->left) && matchTree(node1->right, node2->right); } }
static std::vector<strus::analyzer::PatternMatcherResult> processDocumentAlt( const KeyTokenMap& keytokenmap, const std::vector<TreeNode*> treear, const strus::utils::Document& doc) { std::vector<strus::analyzer::PatternMatcherResult> rt; std::vector<strus::utils::DocumentItem>::const_iterator di = doc.itemar.begin(), de = doc.itemar.end(); for (std::size_t didx=0; di != de; ++di,++didx) { typedef std::pair<KeyTokenMap::const_iterator,KeyTokenMap::const_iterator> CandidateRange; CandidateRange candidateRange = keytokenmap.equal_range( di->termid); KeyTokenMap::const_iterator ri = candidateRange.first, re = candidateRange.second; std::pair<unsigned int,std::size_t> prevkey( 0,0); for (; ri != re; ++ri) { if (ri->first == prevkey.first && ri->second == prevkey.second) continue; prevkey.first = ri->first; prevkey.second = ri->second; //... eliminate dumplicates for redundant keytokens for rules const TreeNode* candidateTree = treear[ ri->second]; unsigned int endpos = di->pos + candidateTree->range(); TreeMatchResult match = matchTree( candidateTree, doc, didx, endpos, ri->first); if (match.valid) { strus::analyzer::PatternMatcherResult result( candidateTree->name(), 0/*value*/, match.ordpos, match.ordpos + match.ordsize, strus::analyzer::Position(0/*start_origseg*/, match.startidx), strus::analyzer::Position(0/*end_origseg*/, match.endidx), match.itemar); rt.push_back( result); } } } return rt; }
// check if node2 tree is subtree of node1 tree bool subtree(treeNode *node1, treeNode *node2){ if(node1 == NULL){ return false; // tree1 is empty } else if(node1->data == node2->data){ return matchTree(node1, node2); } else{ return subtree(node1->left, node2) || subtree(node1->right, node2); } }
bool subTree(TreeNode *r1, TreeNode *r2) { if (NULL == r1) { return false; } if (r1->val == r2->val && matchTree(r1, r2)) { return true; } return (subTree(r1->left, r2) || subTree(r1->right, r2)); }
bool subtree(Node<T> *a, Node<T> *b) { if (!a) return false; if (a->data == b->data) { if (matchTree(a, b)) return true; } return subtree(a->left, b) || subtree(a->right, b); }
bool containsTree(node* bigtree, node* smalltree) { if(smalltree==NULL) return 1; if(bigtree==NULL) return 0; if(bigtree->data==smalltree->data) { if(matchTree(bigtree,smalltree)) return 1; } return containsTree(bigtree->left,smalltree) || containsTree(bigtree->right,smalltree); }
static TreeMatchResult matchTree( const TreeNode* tree, const strus::utils::Document& doc, std::size_t didx, unsigned int endpos, unsigned int firstTerm) { TreeMatchResult rt; if (tree->term() && tree->args().empty()) { if (firstTerm) { if (didx >= doc.itemar.size()) return TreeMatchResult(); if (doc.itemar[ didx].pos < endpos) { endpos = doc.itemar[ didx].pos; } } for (;didx < doc.itemar.size(); ++didx) { if (doc.itemar[ didx].pos > endpos) break; if (doc.itemar[ didx].termid == tree->term()) { if (firstTerm && doc.itemar[ didx].termid != firstTerm) continue; rt = TreeMatchResult( didx, didx+1, doc.itemar[ didx].pos, 1); break; } } } else { switch (tree->op()) { case strus::PatternMatcherInstanceInterface::OpSequenceImm: throw std::runtime_error("not implemented for test: OpSequenceStructImm"); case strus::PatternMatcherInstanceInterface::OpSequenceStruct: { std::vector<TreeNode*>::const_iterator ai = tree->args().begin(), ae = tree->args().end(); for (++ai; ai != ae; ++ai) { TreeMatchResult a_result = matchTree( *ai, doc, didx, endpos, firstTerm); if (!a_result.valid) { rt = TreeMatchResult(); break; } if (a_result.ordpos + tree->range() < endpos) { endpos = a_result.ordpos + tree->range(); } firstTerm = 0; rt.join( a_result); didx = rt.endidx; unsigned int nextpos = a_result.ordpos + a_result.ordsize; for (;didx < doc.itemar.size() && doc.itemar[ didx].pos < nextpos; ++didx){} } if (rt.valid) { if (rt.endidx < doc.itemar.size()) { endpos = doc.itemar[ rt.endidx].pos; } TreeMatchResult delim = matchTree( tree->args()[0], doc, rt.startidx, rt.ordpos + rt.ordsize, 0); if (delim.valid && delim.endidx < rt.endidx) return TreeMatchResult(); } break; } case strus::PatternMatcherInstanceInterface::OpSequence: { std::vector<TreeNode*>::const_iterator ai = tree->args().begin(), ae = tree->args().end(); for (; ai != ae; ++ai) { TreeMatchResult a_result = matchTree( *ai, doc, didx, endpos, firstTerm); if (!a_result.valid) { rt = TreeMatchResult(); break; } if (a_result.ordpos + tree->range() < endpos) { endpos = a_result.ordpos + tree->range(); } firstTerm = 0; rt.join( a_result); didx = rt.endidx; unsigned int nextpos = a_result.ordpos + a_result.ordsize; for (;didx < doc.itemar.size() && doc.itemar[ didx].pos < nextpos; ++didx){} } break; } case strus::PatternMatcherInstanceInterface::OpWithin: case strus::PatternMatcherInstanceInterface::OpWithinStruct: { std::size_t aidx; strus::PatternMatcherInstanceInterface::JoinOperation seqop; if (tree->op() == strus::PatternMatcherInstanceInterface::OpWithin) { aidx = 0; seqop = strus::PatternMatcherInstanceInterface::OpSequence; } else { aidx = 1; seqop = strus::PatternMatcherInstanceInterface::OpSequenceStruct; } std::vector<IndexTuple> argperm = getIndexPermurations( aidx, tree->args().size()); std::vector<IndexTuple>::const_iterator ai = argperm.begin(), ae = argperm.end(); for (; ai != ae; ++ai) { std::vector<TreeNode*> pargs; if (tree->op() == strus::PatternMatcherInstanceInterface::OpWithinStruct) { pargs.push_back( tree->args()[0]); } IndexTuple::const_iterator xi = ai->begin(), xe = ai->end(); for (; xi != xe; ++xi) { pargs.push_back( tree->args()[ *xi]); } TreeNode tree_alt( seqop, pargs, tree->range(), tree->cardinality()); TreeMatchResult candidate = matchTree( &tree_alt, doc, didx, endpos, firstTerm); if (candidate.valid) { if (!rt.valid || candidate.endidx < rt.endidx) { rt = candidate; } } } break; } case strus::PatternMatcherInstanceInterface::OpAnd: throw std::runtime_error( "operator 'And' not implemented yet"); case strus::PatternMatcherInstanceInterface::OpAny: { TreeMatchResult selected; std::vector<TreeNode*>::const_iterator ai = tree->args().begin(), ae = tree->args().end(); for (; ai != ae && !rt.valid; ++ai) { TreeMatchResult candidate = matchTree( *ai, doc, didx, endpos, firstTerm); if (candidate.valid) { if (candidate.ordpos + tree->range() < endpos) { endpos = candidate.ordpos + tree->range(); } if (selected.valid) { if (candidate.endidx < selected.endidx) { selected = candidate; } } else { selected = candidate; } } } rt.join( selected); break; } } } if (rt.valid && tree->variable()) { strus::analyzer::PatternMatcherResultItem item( tree->variable(), ""/*value*/, rt.ordpos, rt.ordpos + rt.ordsize, strus::analyzer::Position(0/*start_origseg*/, rt.startidx), strus::analyzer::Position(0/*end_origseg*/, rt.endidx)); rt.itemar.push_back( item); } return rt; }