public void EliminareRecursivitateStanga() { // Indice pentru lista regulilor de productie int it = 0; // Facem o copie la lista regulilor de productie List <ReguliDeProductie> cReguliProductie = new List <ReguliDeProductie>(); bool[] arr = new bool[_reguliProductie.Count]; Array.Clear(arr, 0, arr.Length); // Indicele nu trebuie sa depaseasca numarul regulilor de productie while (it < _reguliProductie.Count) { // Se determina toate regulile de produtie corespunzatoare unui neterminal ReguliDeProductie regula = _reguliProductie[it]; IEnumerable <ReguliDeProductie> results = _reguliProductie.Where(s => s.GetLeft() == regula.GetLeft()); // Se salveaza rezultatul intr-o lista List <ReguliDeProductie> rList = results.ToList(); // Numarul regulilor de productie corespunzatoare aceluiasi neterminal int counter = rList.Count; CheckLeftRecv(rList, it, cReguliProductie, arr); it = it + counter; } _reguliProductie.Clear(); _reguliProductie = new List <ReguliDeProductie>(cReguliProductie); pNr = _reguliProductie.Count; }
private void CheckLeftRecv(List <ReguliDeProductie> rList, int index, List <ReguliDeProductie> cReguliProductie, bool[] checkArr) { for (int i = 0; i < rList.Count; i++) { int contor = rList[i].GetRight().Length; string first = rList[i].GetRight().FirstOrDefault(); if (rList[i].GetLeft() == first) { if (rList.Count < 2) { Console.WriteLine("Imposibil de eliminar recursivitatea stanga!"); break; } int l_contor = rList[i].GetRight().Length; // Introducem 2 reguli de productie noi ReguliDeProductie newRule1 = new ReguliDeProductie(); ReguliDeProductie newRule2 = new ReguliDeProductie(); // Ambele reguli de productie vor fi pentru acelasi neterminal newRule1.SetLeft(rList[i].GetLeft().ToString() + 'x'); newRule2.SetLeft(rList[i].GetLeft().ToString() + 'x'); // Se adauga noul neterminal in lista _neterminale.Add(newRule1.GetLeft()); // Initializare prima regula de productie introdusa string[] right_1 = rList[i].GetRight().Reverse().Take(l_contor - 1).Reverse().ToArray(); newRule1.SetRight(Helper.Concatenate(right_1, newRule1.GetLeft())); // Initializare a doua regula de productie introdusa string[] right_2 = new string[] { }; newRule2.SetRight(right_2); // Introducem noile reguli de productie in lista cReguliProductie.Add(newRule1); cReguliProductie.Add(newRule2); ReguliDeProductie newRule0 = new ReguliDeProductie(); newRule0.SetLeft(rList[i].GetLeft()); // Aplicam prima parte a regulii de eliminare a recursivitatii if (i == rList.Count - 1) { string[] right = rList[i - 1].GetRight().Take(1).Select(ind => ind.ToString()).ToArray(); string[] str = Helper.Concatenate(right, newRule1.GetLeft()); newRule0.SetRight(str); //_reguliProductie.RemoveAt(index + i - 1); if (checkArr[index + i - 1] == false) { checkArr[index + i - 1] = true; } } else if (i < rList.Count - 1) { string[] right = rList[i + 1].GetRight().Take(1).Select(ind => ind.ToString()).ToArray(); string[] str = Helper.Concatenate(right, newRule1.GetLeft()); newRule0.SetRight(str); if (checkArr[index + i + 1] == false) { checkArr[index + i + 1] = true; } //_reguliProductie.RemoveAt(index + i + 1); } cReguliProductie.Add(newRule0); checkArr[index + i] = true; } } for (int i = 0; i < rList.Count; i++) { if (checkArr[index + i] == false) { cReguliProductie.Add(rList[i]); checkArr[index + i] = true; } } }
public void EliminareReguliIdentice() { // Indice pentru lista regulilor de productie int it = 0; // Facem o copie la lista regulilor de productie List <ReguliDeProductie> cReguliProductie = new List <ReguliDeProductie>(); bool[] arr = new bool[_reguliProductie.Count]; Array.Clear(arr, 0, arr.Length); // Indicele nu trebuie sa depaseasca numarul regulilor de productie while (it < _reguliProductie.Count) { // Se determina toate regulile de produtie corespunzatoare unui neterminal ReguliDeProductie regula = _reguliProductie[it]; IEnumerable <ReguliDeProductie> results = _reguliProductie.Where(s => s.GetLeft() == regula.GetLeft()); // Se salveaza rezultatul intr-o lista List <ReguliDeProductie> rList = results.ToList(); // Numarul regulilor de productie corespunzatoare aceluiasi neterminal int counter = rList.Count; // Functie care elimina regulile de productie care incep la fel CheckElements(rList, it, cReguliProductie, arr); // Se trece la contorizarea urmatorului set de reguli de productie pentru urmatorul neterminal it = it + counter; } _reguliProductie.Clear(); _reguliProductie = new List <ReguliDeProductie>(cReguliProductie); pNr = _reguliProductie.Count; }
private void CheckElements(List <ReguliDeProductie> rList, int index, List <ReguliDeProductie> cReguliProductie, bool[] checkArr) { // Contor utiliat in denumirea noilor neterminale int contor = 0; // Fiecare regula de productie specifica aceluiasi neterminal for (int i = 0; i < rList.Count; i++) { for (int j = i + 1; j < rList.Count; j++) { // Se compara inceputul partii drepte a regulii de productie cu cel al urmatoarelor neterminale int NumberOfCommonElements = Helper.Compare(rList[i].GetRight(), rList[j].GetRight()); // Daca se gaseste cel putin un element comun if (NumberOfCommonElements != 0) { contor++; // Doua reguli pentru A1 ReguliDeProductie newElement1 = new ReguliDeProductie(); ReguliDeProductie newElement2 = new ReguliDeProductie(); // Se seteaza partea stanga a celor doua reguli corespunzatoare neterminalului A1 newElement1.SetLeft(rList[i].GetLeft() + contor.ToString()); newElement2.SetLeft(rList[i].GetLeft() + contor.ToString()); // Se adauga A1 in lista de neterminale _neterminale.Add(newElement1.GetLeft()); // Se seteaza partea dreapta a primei reguli corespunzatoare lui A1 string[] right_1 = rList[i].GetRight().Reverse().Take(rList[i].GetRightPartNumberOfElements() - NumberOfCommonElements).Reverse().ToArray(); newElement1.SetRight(right_1); // Se seteaza partea dreapta pentru a doua regula corespunzatoare lui A1 string[] right_2 = rList[j].GetRight().Reverse().Take(rList[j].GetRightPartNumberOfElements() - NumberOfCommonElements).Reverse().ToArray(); newElement2.SetRight(right_2); //// Adauugam cele doua reugli de productie la lista cReguliProductie.Add(newElement1); cReguliProductie.Add(newElement2); // Se ia partea comuna a celor coua reguli (a) string[] right = rList[i].GetRight().Take(NumberOfCommonElements).ToArray(); // Se concateneaza cu neterminalul introdus (A1) ReguliDeProductie newElement0 = new ReguliDeProductie(); newElement0.SetLeft(rList[i].GetLeft()); newElement0.SetRight(Helper.Concatenate(right, newElement1.GetLeft())); // Se adauga noua regula de productie in lista cReguliProductie.Add(newElement0); // se bifeaza regula de productie folosita din sirul original checkArr[index + i] = true; // Se elimina A -> ac if (checkArr[index + j] == false) { //_reguliProductie.RemoveAt(index + j); checkArr[index + j] = true; } } } if (checkArr[index + i] == false) { cReguliProductie.Add(rList[i]); checkArr[index + i] = true; } } }