Cod sursa(job #750162)

Utilizator keisecGinghina Cristian keisec Data 21 mai 2012 02:14:57
Problema Trie Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 8.06 kb
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<fstream>
#include<string>
#include<cstring>
#include<queue>

using namespace std;

// -----------------------------------Gramatica------------------------

struct G
{
	string P1[100];
	char S,P0[100];
	int size;
};

void Limbaj(G a,int k,string c="")
{
	if(c=="")c=a.S;
	if(k>=c.size())
	{
		if(c[c.size()-1]<='z'&&c[c.size()-1]>='a')
			cout<<c<<"\n";
		for(int i=0;i<a.size;i++)
		{
			if(a.P0[i]==c[c.size()-1])
			{
				string aux=c;
				aux.erase(aux.end()-1);
				aux+=a.P1[i];
				Limbaj(a,k,aux);
			}
		}
	}
}

G citG(istream& in)
{
	G a;
	in>>a.S;
	in>>a.size;
	for(int i=0;i<a.size;i++)
		in>>a.P0[i]>>a.P1[i];
	return a;
}

//----------------------------liste--------------------------------

struct nod
{
	int i;
	nod *n;
};

void push_back(nod*&n,int x)
{
	if(!n)
	{
		n=new nod;
		n->n=NULL;
		n->i=x;
	}
	else push_back(n->n,x);
}


//-----------------------------AFD---------------------------------

struct AFD
{
	int q_act,q0,tranz[100][26],nr_stari;
	bool finale[100];
	AFD(int x=100)
	{
		nr_stari=x;
		for(int i=0;i<nr_stari;i++)
		{
			finale[i]=false;
			for(int j=0;j<26;j++)
				tranz[i][j]=-1;
		}
	}
};

void Limbaj(AFD a,int k,string c="")
{
	if(c=="")a.q_act=a.q0;
	if(k>=c.size())
	{
		if(a.finale[a.q_act])
			cout<<c<<"\n";
		for(int i=0;i<26;i++)
			if(a.tranz[a.q_act][i]!=-1)
			{
				string aux=c+(char)(i+'a');
				int iaux=a.q_act;
				a.q_act=a.tranz[a.q_act][i];
				Limbaj(a,k,aux);
				a.q_act=iaux;
			}
	}
}

bool valid(AFD a,string str)
{
	a.q_act=a.q0;
	for(int i=0;i<str.size();i++)
	{
		if(a.tranz[a.q_act][str[i]-'a']==-1)return false;
		a.q_act=a.tranz[a.q_act][str[i]-'a'];
	}
	if(a.finale[a.q_act])return true;
	return false;
}


AFD citAFD(istream& in)
{
	AFD a;
	int t;
	in>>a.q0>>t>>a.nr_stari;
	for(int i=0;i<a.nr_stari;i++)
	{
		int x;
		in>>x;
		if(x)
			a.finale[i]=true;
	}
	for(int i=0;i<t;i++)
	{
		int a1,a2;
		char a3;
		in>>a1>>a3>>a2;
		a.tranz[a1][a3-'a']=a2;
	}
	return a;
}
//--------------------------------------AFN--------------------------------------

struct AFN
{
	int q_act,q0,nr_stari;
	nod*tranz[100][26];
	bool finale[100];
	AFN(int x=100)
	{
		nr_stari=x;
		for(int i=0;i<nr_stari;i++)
		{
			finale[i]=false;
			for(int j=0;j<26;j++)
				tranz[i][j]=NULL;
		}
	}
};

void Limbaj(AFN a,int k,string c="")
{
	if(c=="")a.q_act=a.q0;
	if(k>=c.size())
	{
		if(a.finale[a.q_act])
			cout<<c<<"\n";
		for(int i=0;i<26;i++)
		{
			nod *pnaux=a.tranz[a.q_act][i];
			int iaux=a.q_act;
			string saux=c+(char)(i+'a');
			while(pnaux)
			{
				a.q_act=pnaux->i;
				Limbaj(a,k,saux);
				pnaux=pnaux->n;
			}
			a.q_act=iaux;
		}
	}
}

bool valid(AFN a,string str)
{
	int p,u,k,c[100];
	p=0;
	c[p]=a.q0;
	u=k=1;
	for(int i=0;i<str.size();i++)
	{
		if(p==u)return false;
		nod*pnaux;
		while(p<k)
		{
			pnaux=a.tranz[c[p%100]][str[i]-'a'];
			while(pnaux)
			{
				c[(u++)%100]=pnaux->i;
				pnaux=pnaux->n;
			}
			p++;
		}
		k=u;
	}
	while(p<u)
	{
		if(a.finale[c[p%100]])
			return true;
		p++;
	}

	return false;
}


AFN citAFN(istream&in)
{
	int t;
	AFN a;
	in>>a.q0>>t>>a.nr_stari;
	for(int i=0;i<a.nr_stari;i++)
	{
		int x;
		in>>x;
		if(x)
			a.finale[i]=true;
	}
	for(int i=0;i<t;i++)
	{
		int a1,a2;
		char a3;
		in>>a1>>a3>>a2;
		push_back(a.tranz[a1][a3-'a'],a2);
	}
	return a;
}
//---------------------------------lambda AFN------------------------------------

struct lAFN:public AFN
{
	nod*ltranz[100];
	lAFN(int x=100):AFN(x)
	{
		for(int i=0;i<nr_stari;i++)
			ltranz[i]=NULL;
	}
};

void Limbaj(lAFN a,int k,string c="")
{
	if(c=="")a.q_act=a.q0;
	if(k>=c.size())
	{
		if(a.finale[a.q_act])
			cout<<c<<"\n";
		nod*pnaux=a.ltranz[a.q_act];
		int iaux=a.q_act;
		while(pnaux)
		{
			a.q_act=pnaux->i;
			pnaux=pnaux->n;
			Limbaj(a,k,c);
		}
		a.q_act=iaux;
		for(int i=0;i<26;i++)
		{
			pnaux=a.tranz[a.q_act][i];
			while(pnaux)
			{
				a.q_act=pnaux->i;
				pnaux=pnaux->n;
				string saux=c+(char)(i+'a');
				Limbaj(a,k,saux);
			}
			a.q_act=iaux;
		}
	}
}

bool valid(lAFN a,string str)
{
	int u=1,p=0,k=u,c[1000];
	c[p]=a.q0;
	nod*pnaux;
	for(int i=0;i<str.size();i++)
	{
		if(p==u)return false;
		for(int j=p;j<u;j++)
		{
			pnaux=a.ltranz[c[j%1000]];
			while(pnaux)
			{
				c[(u++)%1000]=pnaux->i;
				pnaux=pnaux->n;
			}
		}
		k=u;
		for(;p<k;p++)
		{
			pnaux=a.tranz[c[p%1000]][str[i]-'a'];
			while(pnaux)
			{
				c[(u++)%1000]=pnaux->i;
				pnaux=pnaux->n;
			}
		}
	}
	for(int j=p;j<u;j++)
	{
		pnaux=a.ltranz[c[j%1000]];
		while(pnaux)
		{
			c[(u++)%1000]=pnaux->i;
			pnaux=pnaux->n;
		}
	}
	for(;p<u;p++)
		if(a.finale[c[p%100]])
			return true;
	return false;
}

lAFN citlAFN(istream&in)
{
	int t;
	lAFN a;
	in>>a.q0>>t>>a.nr_stari;
	for(int i=0;i<a.nr_stari;i++)
	{
		int x;
		in>>x;
		if(x)
			a.finale[i]=true;
	}
	for(int i=0;i<t;i++)
	{
		int a1,a2;char a3;
		in>>a1>>a3>>a2;
		if(a3=='0')
		{
			push_back(a.ltranz[a1],a2);
			continue;
		}
		push_back(a.tranz[a1][a3-'a'],a2);
	}
	return a;
}
//-------------------------------------TRIE--------------------------------------

struct TRIE
{
	TRIE*fiu[26];
	int nrfii,cnt;
	TRIE()
	{
		cnt=nrfii=0;
		memset(fiu,0,sizeof(fiu));
	}
};

void add(TRIE *&a,string str)
{
	TRIE *aux=a;
	for(int i=0;i<str.size();i++)
	{
		if(!a->fiu[str[i]-'a'])
		{
			a->fiu[str[i]-'a']=new TRIE;
			a->nrfii++;
		}
		a=a->fiu[str[i]-'a'];
	}
	a->cnt++;
	a=aux;
}

void rem(TRIE*&a,string str)
{
	TRIE **stiva=(TRIE**)malloc(sizeof(TRIE*)*str.size());
	for(int i=0;i<str.size();i++)
	{
		stiva[i]=a;
		a=a->fiu[str[i]-'a'];
	}
	a->cnt--;
	for(int i=str.size()-1;i>=0;i--)
	{
		if(stiva[i]->fiu[str[i]-'a']->cnt==0&&stiva[i]->fiu[str[i]-'a']->nrfii==0)
		{
			delete stiva[i]->fiu[str[i]-'a'];
			stiva[i]->nrfii--;
			stiva[i]->fiu[str[i]-'a']=0;
		}
	}
	a=stiva[0];
	if(!a->fiu[str[0]-'a'])a->nrfii--;
}

int aparitii(TRIE *a,string str)
{
	for(int i=0;i<str.size();i++)
	{
		if(a->fiu[str[i]-'a'])
			a=a->fiu[str[i]-'a'];
		else
			return 0;
	}
	return a->cnt;
}

int prefix(TRIE *a,string str)
{
	int k=0;
	for(int i=0;i<str.size();i++)
		if(a->fiu[str[i]-'a'])
		{
			k++;
			a=a->fiu[str[i]-'a'];
		}
		else
			return k;
	return k;
}
		


//-------------------------------------main--------------------------------------
int main()
{
	G a1;
	AFD a2;
	AFN a3;
	lAFN a4;
	TRIE *a5=new TRIE;
	cout<<"Alege optiunea:\n";
	cout<<"1.Limbaj recunoscut de o gramatica,cuvintele <= k;\n";
	cout<<"2.Limbaj recunoscut de un AFD, cuvintele <=k;\n";
	cout<<"3.Limbaj reconuscut de un AFN, cuvintele <=k;\n";
	cout<<"4.Limbaj recunoscut de un Lambda AFN, cuvintele <=k;\n";
	cout<<"5.W apartine lui L(AFD);\n";
	cout<<"6.W apartine lui L(AFN):\n";
	cout<<"7.W apartine lui L(Lambda AFN);\n";
	cout<<"8.Trie;\n";
	int x,k;
	string W;
//	cin>>x;
	x=8;
	ifstream f;
	ofstream g;
	switch (x)
	{
		case 1:
			f.open("Gram.in");
			a1=citG(f);
			cout<<"k=";
			cin>>k;
			Limbaj(a1,k);
			break;
		case 2:
			f.open("AFD.in");
			a2=citAFD(f);
			cout<<"k=";
			cin>>k;
			Limbaj(a2,k);
			break;
		case 3:
			f.open("AFN.in");
			a3=citAFN(f);
			cout<<"k=";
			cin>>k;
			Limbaj(a3,k);
			break;
		case 4:
			f.open("lAFN.in");
			a4=citlAFN(f);
			cout<<"k=";
			cin>>k;
			Limbaj(a4,k);
			break;
		case 5:
			f.open("AFD.in");
			a2=citAFD(f);
			cout<<"W=";
			cin>>W;
			if(W=="0")
				W="";
			if(valid(a2,W))
				cout<<"Apartine limbajului!\n";
			else
				cout<<"Nu apartine limbajului!\n";
			break;
		case 6:
			f.open("AFN.in");
			a3=citAFN(f);
			cout<<"W=";
			cin>>W;
			if(W=="0")
				W="";
			if(valid(a3,W))
				cout<<"Apartine limbajului!\n";
			else
				cout<<"Nu apartine limbajului!\n";
			break;
		case 7:
			f.open("lAFN.in");
			a4=citlAFN(f);
			cout<<"W=";
			cin>>W;
			if(W=="0")
				W="";
			if(valid(a4,W))
				cout<<"Apartine limbajului!\n";
			else
				cout<<"Nu apartine limbajului!\n";
			break;
		case 8:
			f.open("trie.in");
			g.open("trie.out");
			while(!f.eof())
			{
				f>>x;
				if(!f.eof())
				{
					f>>W;
					switch(x)
					{
						case 0:
							add(a5,W);
							break;
						case 1:
							rem(a5,W);
							break;
						case 2:
							g<<aparitii(a5,W)<<"\n";
							break;
						case 3:
							g<<prefix(a5,W)<<"\n";
							break;
					}
				}
			}
			break;
	}
	f.close();
	g.close();
	return 0;
}