public void SearchTest()
        {
            var numbers          = new [] { -10, -8, 0, 10, 500 };
            var indexerDelegates = new IndexerDelegates <int, int>(index => numbers[index], index => index);

            // Object found.
            BinarySearchResult <int> result = BinarySearch <int, int> .Search(0, numbers.GetIndexInterval(), indexerDelegates);

            Assert.AreEqual(true, result.IsObjectFound);
            Assert.AreEqual(true, result.IsObjectInRange);
            Assert.AreEqual(0, result.Found.Object);
            Assert.IsNull(result.NotFound);

            // Object found, border.
            result = BinarySearch <int, int> .Search(500, numbers.GetIndexInterval(), indexerDelegates);

            Assert.AreEqual(true, result.IsObjectFound);
            Assert.AreEqual(true, result.IsObjectInRange);
            Assert.AreEqual(500, result.Found.Object);
            Assert.IsNull(result.NotFound);

            // Object not found, but in range.
            result = BinarySearch <int, int> .Search(-9, numbers.GetIndexInterval(), indexerDelegates);

            Assert.AreEqual(false, result.IsObjectFound);
            Assert.AreEqual(true, result.IsObjectInRange);
            Assert.AreEqual(-10, result.NotFound.Smaller);
            Assert.AreEqual(-8, result.NotFound.Bigger);
            Assert.IsNull(result.Found);

            // Object not found, out of range, left.
            result = BinarySearch <int, int> .Search(-20, numbers.GetIndexInterval(), indexerDelegates);

            Assert.AreEqual(false, result.IsObjectFound);
            Assert.AreEqual(false, result.IsObjectInRange);
            Assert.IsNull(result.NotFound);
            Assert.IsNull(result.Found);

            // Object not found, out of range, right.
            result = BinarySearch <int, int> .Search(600, numbers.GetIndexInterval(), indexerDelegates);

            Assert.AreEqual(false, result.IsObjectFound);
            Assert.AreEqual(false, result.IsObjectInRange);
            Assert.IsNull(result.NotFound);
            Assert.IsNull(result.Found);
        }
		public void SearchTest()
		{
			var numbers = new [] { -10, -8, 0, 10, 500 };
			var indexerDelegates = new IndexerDelegates<int, int>( index => numbers[ index ], index => index );

			// Object found.
			BinarySearchResult<int> result = BinarySearch<int, int>.Search( 0, numbers.GetIndexInterval(), indexerDelegates );
			Assert.AreEqual( true, result.IsObjectFound );
			Assert.AreEqual( true, result.IsObjectInRange );
			Assert.AreEqual( 0, result.Found.Object );
			Assert.IsNull( result.NotFound );

			// Object found, border.
			result = BinarySearch<int, int>.Search( 500, numbers.GetIndexInterval(), indexerDelegates );
			Assert.AreEqual( true, result.IsObjectFound );
			Assert.AreEqual( true, result.IsObjectInRange );
			Assert.AreEqual( 500, result.Found.Object );
			Assert.IsNull( result.NotFound );

			// Object not found, but in range.
			result = BinarySearch<int, int>.Search( -9, numbers.GetIndexInterval(), indexerDelegates );
			Assert.AreEqual( false, result.IsObjectFound );
			Assert.AreEqual( true, result.IsObjectInRange );
			Assert.AreEqual( -10, result.NotFound.Smaller );
			Assert.AreEqual( -8, result.NotFound.Bigger );
			Assert.IsNull( result.Found );

			// Object not found, out of range, left.
			result = BinarySearch<int, int>.Search( -20, numbers.GetIndexInterval(), indexerDelegates );
			Assert.AreEqual( false, result.IsObjectFound );
			Assert.AreEqual( false, result.IsObjectInRange );
			Assert.IsNull( result.NotFound );
			Assert.IsNull( result.Found );

			// Object not found, out of range, right.
			result = BinarySearch<int, int>.Search( 600, numbers.GetIndexInterval(), indexerDelegates );
			Assert.AreEqual( false, result.IsObjectFound );
			Assert.AreEqual( false, result.IsObjectInRange );
			Assert.IsNull( result.NotFound );
			Assert.IsNull( result.Found );
		}
示例#3
0
        /// <summary>
        ///   Searches for the given object.
        /// </summary>
        /// <param name = "toFind">The object to search for.</param>
        /// <param name = "range">The range in which to search.</param>
        /// <param name = "indexOperations">Operations that can be done on an indexer.</param>
        /// <returns>The found object, or it's nearest matches.</returns>
        public static BinarySearchResult <TObject> Search(
            TObject toFind,
            Interval <TIndex> range,
            IndexerDelegates <TObject, TIndex> indexOperations)
        {
            // Make sure start and end of range are valid.
            // TODO: This is only necessary the first call of the recursion. Implementing the search as a loop could be more performant.
            range = new Interval <TIndex>(
                indexOperations.GetNearestIndex(range.Start),
                indexOperations.GetNearestIndex(range.End));

            // Get object near the center of the range.
            TIndex  center       = indexOperations.GetNearestIndex(range.Center);
            TObject centerObject = indexOperations.GetByIndex(center);

            // Check whether desired object was found.
            int orderToCenter = toFind.CompareTo(centerObject);

            // See whether finished.
            bool isObjectFound    = orderToCenter == 0;
            bool hasNoMoreObjects = IndexComparer.Equals(center, range.Start) || IndexComparer.Equals(center, range.End);
            bool isFinished       = isObjectFound || hasNoMoreObjects;

            if (!isFinished)
            {
                // Split interval in the middle.
                Interval <TIndex> smaller, bigger;
                range.Split(center, SplitOption.Both, out smaller, out bigger);

                // Continue recursively in the range in which the object lies.
                Interval <TIndex> inRange = orderToCenter > 0 ? bigger : smaller;
                return(Search(toFind, inRange, indexOperations));
            }
            else
            {
                TObject smaller = indexOperations.GetByIndex(range.Start);
                TObject bigger  = indexOperations.GetByIndex(range.End);

                // Find the desired object.
                TObject foundObject = default(TObject);
                if (isObjectFound)
                {
                    foundObject = centerObject;
                }
                else
                {
                    if (toFind.CompareTo(smaller) == 0)
                    {
                        isObjectFound = true;
                        foundObject   = smaller;
                    }
                    else if (toFind.CompareTo(bigger) == 0)
                    {
                        isObjectFound = true;
                        foundObject   = bigger;
                    }
                }

                // Return result.
                bool isObjectInRange = toFind.CompareTo(smaller) >= 0 && toFind.CompareTo(bigger) <= 0;
                return(new BinarySearchResult <TObject>
                {
                    IsObjectInRange = isObjectInRange,
                    IsObjectFound = isObjectFound,
                    Found = isObjectFound ? new BinarySearchResult <TObject> .FoundResult(foundObject) : null,
                    NotFound = isObjectFound || !isObjectInRange ? null : new BinarySearchResult <TObject> .NotFoundResult(smaller, bigger)
                });
            }
        }