1

I have an object array and I want to search the date / day property (user decides) by using binary search.

**EDIT: I read the SharesArray[mid].Date values (and day values) from a text file and examples are: 05/02/2015, 14/10/2014.The searchString value would be gained from the user but would be in the same format as the date values. **

This is my first attempt so I am just trying the date property:

int high, low, mid;
high = SharesArray.Length - 1;
low = 0;

while (low <= high)
{
    mid = (low + high) / 2;
    if (String.Compare(SharesArray[mid].Date, searchString, true) == 0)
    {
        break;
    }
    else if (String.Compare(SharesArray[mid].Date, searchString, true) > 0)
    {
        high = mid - 1;
    }
    else if (String.Compare(SharesArray[mid].Date, searchString, true) < 0)
    {
        low = mid + 1;
    }

I have also tried the last else if statement as just else and that doesn't make any difference.

Also, does it matter what way round string1 and string2 are in the String.Compare part?

15
  • The order of strings in your String.Compare is irrelevant. Commented Apr 9, 2015 at 21:32
  • Could you please show us how Date is defined in SharesArray and give us an example of what value searchString could be and what possible values SharesArray[mid].Date could be? Commented Apr 9, 2015 at 21:41
  • I thought so too but when I used a breakpoint and watched the flow of control it went to different elements in my array when I swapped them. Commented Apr 9, 2015 at 21:41
  • I have edited for you John Commented Apr 9, 2015 at 21:47
  • @Steve The order in the Compare call is most definitely not irrelevant and the mid calculation is correct, although it is potentially vulnerable to an overflow, so mid = low + ((high - low) >> 1) would be better Commented Apr 9, 2015 at 21:51

2 Answers 2

1

Summarizing an answer from the Q&A in the comments of the question, with a bit of additional context.

For binary search, there are a few ingredients you need to take care of

  1. The input array to the binary search function must be sorted.
  2. Given the algorithm you have implemented, they must be sorted in ascending order.
  3. You must have a three-way comparison function, that for compare(lhs, rhs) returns: < 0 if lhs < rhs, > 0 if lhs > rhs and 0 if lhs == rhs.
  4. The order of the arguments in the compare function matters, if you switch them, you will be taking the wrong branch and changing the upper search bound instead of the lower, or the other way around.
  5. For your implementation, you had the order correct, with lhs : SharesArray[mid].Date and rhs = searchString.
  6. Because you are comparing dates, you need to use the DateTime.Compare function, and convert your date strings to DateTime instances, using DateTime.ParseExact(myString, "dd/MM/yyyy", CultureInfo.InvariantCulture);. With a string comparison you would get wrong results such as "05/02/2015" < "14/10/2014".

And then there is one more anecdotal remark to make (see here):

The calculation of the pivot value mid is susceptible to integer overflow. If you calculate it as

mid = (low + high) / 2;

then low + high could become larger than fits in an integer.

The preferred way of calculating mid is therefore

`mid = low + ((high - low) >> 1);`.
Sign up to request clarification or add additional context in comments.

1 Comment

@EmmaD Since Alex's answer from the comments worked for you probably, for the benefit of the future generations, it's worth to accept this summary as an answer.
0

Have you considered LINQ?

var searchIndex = SharesArray
    .Select(s => s.Date)
    .ToList()
    .BinarySearch(searchString);

2 Comments

I am trying not to use the BinarySearch in built method
@EmmaD anything you're trying to achieve should be mentioned in the question.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.