コード例 #1
0
        public IEnumerable <TEdit> CalculateEdit <TEdit>(
            ILevenstainMatrix matrix,
            IList <TSource> source,
            IList <TTarget> target,
            Func <TSource, TTarget, TEdit> editSelector,
            bool reverse = false)
        {
            var result = InternalCalculateEdit(matrix, source, target, editSelector);

            return(reverse ? result : result.Reverse()); //default is already reversed
        }
コード例 #2
0
        private IEnumerable <TEdit> InternalCalculateEdit <TEdit>(
            ILevenstainMatrix matrix,
            IList <TSource> source,
            IList <TTarget> target,
            Func <TSource, TTarget, TEdit> editSelector)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }
            if (target == null)
            {
                throw new ArgumentNullException(nameof(target));
            }
            if (editSelector == null)
            {
                throw new ArgumentNullException(nameof(editSelector));
            }
            if (matrix == null)
            {
                throw new ArgumentNullException(nameof(matrix));
            }
            if (matrix.M != (source.Count + 1) || matrix.N != (target.Count + 1))
            {
                throw new ArgumentOutOfRangeException("Invalid matrix size.");
            }
            if (Options == null)
            {
                throw new ArgumentNullException(nameof(Options));
            }
            int i = matrix.M - 1;
            int j = matrix.N - 1;

            while (i != 0 || j != 0)
            {
                if (i == 0)
                {
                    yield return(editSelector(default(TSource), target[j - 1]));

                    j--;
                    continue;
                }
                if (j == 0)
                {
                    yield return(editSelector(source[i - 1], default(TTarget)));

                    i--;
                    continue;
                }
                var ss1  = source[i - 1];
                var ss2  = target[j - 1];
                var diag = matrix[i - 1, j - 1] + Options.GetUpdateCost(ss1, ss2);
                var left = matrix[i, j - 1] + Options.GetCreateCost(ss2);
                var up   = matrix[i - 1, j] + Options.GetDeleteCost(ss1);
                if (diag <= left && diag <= up)
                {
                    yield return(editSelector(ss1, ss2));

                    i--;
                    j--;
                }
                else if (left <= diag && left <= up)
                {
                    yield return(editSelector(default(TSource), ss2));

                    j--;
                }
                else if (up <= diag && up <= left)
                {
                    yield return(editSelector(ss1, default(TTarget)));

                    i--;
                }
                else
                {
                    throw new InvalidOperationException();
                }
            }
        }