Example #1
0
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;
	}
}