/// <summary> /// Final part of the shunting yard algorithm /// Pop and push elements to evaluate the search expression /// Shlomo 2020 /// </summary> /// <param name="result">Array of vehicle registrations that match search</param> /// <param name="searchAlgorithm">Search algorithm instance to use</param> public void searchFleet(out string[] result, SearchAlgorithm searchAlgorithm) { // Create and instantiate a new empty Stack for result sets. Stack setStack = new Stack(); HashSet <string> hs1; HashSet <string> hs2; HashSet <string> hs; int idx; String[] temp = new string[] { }; for (int i = 0; i < searchAlgorithm.Postfix.Count; i++) { if (searchAlgorithm.Postfix[i].Equals("AND")) { // pop two sets off the stack and apply Intersect, push back result hs1 = (HashSet <string>)setStack.Pop(); hs2 = (HashSet <string>)setStack.Pop(); temp = hs1.ToArray <string>(); // copy the elements of the set hs1 hs = new HashSet <string>(temp); // make a deep copy of hs1 hs.IntersectWith(hs2); // apply the Intersect to the new set setStack.Push(hs); // push a reference to a new set } else if (searchAlgorithm.Postfix[i].Equals("OR")) { // pop two sets off the stack and apply Union hs1 = (HashSet <string>)setStack.Pop(); hs2 = (HashSet <string>)setStack.Pop(); temp = hs1.ToArray <string>(); // copy the elements of the set hs1 hs = new HashSet <string>(temp); // make a deep copy of hs1 hs.UnionWith(hs2); // apply the Union to the new set setStack.Push(hs); // push a reference to a new set } else { // here if an operand idx = attributeSets.IndexOfKey(searchAlgorithm.Postfix[i]); // identify attribute set if (idx >= 0) { hs1 = (HashSet <string>)attributeSets.GetByIndex(idx); setStack.Push(hs1); // note: pushing a reference, not the actual set } else { throw new FormatException(string.Format("Invalid attribute {0}. Use attributes that exist on a vehicle.", searchAlgorithm.Postfix[i])); } } } if (setStack.Count == 1) { //hs1 = (HashSet<string>)attributeSets.GetByIndex(1); hs1 = (HashSet <string>)setStack.Pop(); result = hs1.ToList().ToArray(); } else { throw new Exception("Invalid search query provided. Did you add an extra parenthesis?"); } }
/// <summary> /// Search using specified algorithm /// </summary> /// <param name="searchAlgorithm">Search algorithm instance to use</param> /// <returns></returns> private string[] search(SearchAlgorithm searchAlgorithm) { searchFleet(out string[] result, searchAlgorithm); if (result.Length == 0) { throw new Exception("No matches found for this search query. Perhaps make your query less specific."); } return(result); }