bool Chain::match (const Chain* c, cMatchsType& res ) const { // // find parts of non-substituent type // vector<markType> ns_t; vector<cMatchType> asmb; for (int i=0; i < c->listOfParts.size ();) { Part* p = c->listOfParts[i]; string ctg = p->getPartCtg (); int startpos = i; if (ctg != "substituent") { bool found = false; int j = i+1; for (; j < c->listOfParts.size (); j++) { Part* p1 = c->listOfParts[j]; string ctg1 = p1->getPartCtg (); if (ctg1 == "substituent") {found = true;break;} } if (j == c->listOfParts.size ()) found = true; if (found) { ns_t.push_back (make_pair(i, j-1)); i = j+1; } } else i++; } if (ns_t.size () > 0) { vector< markType >* m_pos = new vector< markType > [ns_t.size ()]; // // for each non-substituent part, find its possible // matching points in this chain // int permAll = 1; for (int cnt =0; cnt < ns_t.size (); cnt++) { int start = ns_t[cnt].first; int end = ns_t[cnt].second; int diff = end-start; string mkey = c->genUnicode (start, end, true); for (string::size_type pos = 0; (pos = unicode.find (mkey, pos)) != string::npos; pos++) { int spos = count (unicode.begin (), unicode.begin ()+pos, ']'); int epos = spos + diff; m_pos[cnt].push_back (make_pair (spos, epos)); } if (m_pos[cnt].size () == 0) { delete [] m_pos; return false; } else permAll *= m_pos[cnt].size (); } // // find possible matching combinations // for (int i =0; i < permAll; i++) { int lastp = -1; cMatchType tmp; int divide = i; for (int j=0; j< ns_t.size (); j++) { markType p = m_pos[j][divide % m_pos[j].size ()]; if (p.first <= lastp) { tmp.clear (); break; } else { lastp = p.second; tmp.push_back (p); } divide /= m_pos[j].size (); } assert (tmp.size () == ns_t.size ()); if (!tmp.empty ()) asmb.push_back (tmp); } delete [] m_pos; if (asmb.size () == 0) return false; } // cout << "\nasmb.size () == " << asmb.size () << endl; // insert substituent pieces into asmb // if there are only substituent-type parts if (ns_t.size () == 0) { int l1 = 0; int u1 = static_cast<int> (c->listOfParts.size ())-1; int l2 = 0; int u2 = listOfParts.size ()-1; assert (u1 >= l1); assert (u2 >= l2); bool mok = substituent_m (l1, u1, l2, u2, c, res); if (mok && res.size() > 0) return true; else return false; } else { assert (asmb.size () > 0); // if there are non-substituent-type part for (int i=0; i< asmb.size (); i++) { vector<cMatchType> AssembleMatch; bool found = true; // // *it ==> pair<int,int> // cMatchType::const_iterator it = asmb[i].begin (); // // find matchings of first block of substituent-type parts // if (ns_t[0].first != 0) { vector<cMatchType> tmp; bool mok = substituent_m ( 0, ns_t[0].first-1, 0, it->first-1, c, tmp ); if (mok && tmp.size () > 0) { for (int j = 0; j < tmp.size (); j++) AssembleMatch.push_back (tmp[j]); } else return false; } int l1, u1, l2, u2; l1 = u1 = l2 = u2 = 0; for (int j=0; j < ns_t.size (); j++) { // // add non-substituent type matching // if (j == 0 && AssembleMatch.size () == 0) { cMatchType initial; for (int l=it->first; l <= it->second; l++) initial.push_back (make_pair (l,l)); AssembleMatch.push_back (initial); } else { for (int k =0; k < AssembleMatch.size (); k++) for (int l=it->first; l <= it->second; l++) AssembleMatch[k].push_back ( make_pair (l,l) ); } // // add substituent type matching // vector<cMatchType> tmp; l1 = ns_t[j].second+1; if (j == ns_t.size ()-1) u1 = c->listOfParts.size ()-1; else u1 = ns_t[j+1].first-1; l2 = it->second+1; if (j == ns_t.size ()-1) u2 = listOfParts.size ()-1; else u2 = (++it)->first-1; //it add one object // no substituent-type parts if (j == ns_t.size ()-1) if (u1 < l1 && u2 < l2) continue; bool mok = substituent_m (l1, u1, l2, u2, c, tmp); if (mok && tmp.size () > 0) { vector<cMatchType> __matchExp; for (int k =0; k < AssembleMatch.size ();k++) { for (int l=0; l< tmp.size (); l++) { cMatchType expandMatch = AssembleMatch[k]; list<markType>::iterator iter = tmp[l].begin (); while (iter != tmp[l].end ()) expandMatch.push_back (*iter++); __matchExp.push_back (expandMatch); } } AssembleMatch.clear (); AssembleMatch = __matchExp; } else { found = false; break; } } if (!found) continue; else { for (int j=0; j < AssembleMatch.size (); j++) res.push_back (AssembleMatch[j]); } } if (res.empty ()) return false; return true; } }