Esempio n. 1
0
        private static T[] DoArray <T>(Pair previous, IRegex <T> regex, IList <T> sequence, int count) where T : IComparable <T>
        {
            int length = previous.End - previous.Begin + regex.GetSubsequence(count - 1).Count;

            T[] ans = new T[length];
            for (int j = 0; j < length; j++)
            {
                ans[j] = sequence[j + previous.Begin];
            }
            return(ans);
        }
Esempio n. 2
0
        /// <summary>
        /// where method a la LINQ for IRegex objects, return all subsequences
        /// that satisfy the IRegex object
        /// </summary>
        /// <typeparam name="T"> must implement IComparable of <typeparamref name="T"/></typeparam>
        /// <param name="sequence">initial sequence</param>
        /// <param name="function">function that must return regex object for any first (object) argument</param>
        /// <returns>
        /// all subsequences a la regex through IEnumerable interface (lazy)
        /// </returns>
        public static IEnumerable <IList <T> > Where <T>(this IList <T> sequence, Func <object, IRegex <T> > function)
            where T : IComparable <T>
        {
            //get input regex and check of the correctness
            IRegex <T> regex = function(null);
            int        count = regex.CountOfSubsequences;

            if (count == 0)
            {
                throw new Exception("Uncorrect regex!");
            }
            if (regex.IsFirstAny)
            {
                throw new Exception("FirstAny!");
            }
            if (regex.IsLastAny)
            {
                throw new Exception("LastAny!");
            }

            //initialization for the algorithm
            int[] positions = new int[count];
            for (int i = 0; i < count; i++)
            {
                int next = sequence.Find(i == 0 ? 0 : positions[i - 1] + regex.GetSubsequence(i - 1).Count, regex.GetSubsequence(i));
                if (next == -1)
                {
                    yield break;
                }
                positions[i] = next;
            }
            // pair with begin and end of the previous answer
            Pair previous = new Pair(positions[0], positions[count - 1]);

            while (true)
            {
                bool isFind = false;
                for (int i = count - 1; i >= 0; i--)
                {
                    // move first which can
                    int next = sequence.Find(positions[i] + 1, regex.GetSubsequence(i));
                    if (next < 0)
                    {
                        continue;
                    }
                    positions[i] = next;
                    isFind       = true;
                    //try to move others
                    for (int j = i + 1; j < count; j++)
                    {
                        next = sequence.Find(positions[j - 1] + regex.GetSubsequence(j - 1).Count, regex.GetSubsequence(j));
                        if (next == -1)
                        {
                            isFind = false;
                            break;
                        }
                        positions[j] = next;
                    }
                    //if all is good, then return the result
                    if (isFind)
                    {
                        Pair current = new Pair(positions[0], positions[count - 1]);
                        if (current == previous)
                        {
                            break;
                        }
                        T[] ans = DoArray(previous, regex, sequence, count);
                        //change previous result for future
                        previous = current;
                        yield return(ans);

                        break;
                    }
                }
                if (!isFind)
                {
                    yield return(DoArray(previous, regex, sequence, count));

                    ;
                    yield break;
                }
            }
        }