5

我的任务是创建两个单独的程序,一个我已经完成的线性搜索程序和一个二分搜索程序。这些程序还必须计算在搜索过程中进行的比较次数。我的线性搜索程序已经计算了比较次数,而我的二进制搜索程序却不能。二进制搜索的代码如下所示:

using System;
using System.Collections.Generic;

public class Example
{
public static void Main()
{

    Console.WriteLine("Input number you would like to search for");

    String Look_for = Console.ReadLine();

    int Lookfor;

    int.TryParse(Look_for, out Lookfor);

    {
        List<int> numbers = new List<int>();

        numbers.Add(1); 
        numbers.Add(2); 
        numbers.Add(3); 
        numbers.Add(4); 
        numbers.Add(5); 
        numbers.Add(6); 
        numbers.Add(7); 
        numbers.Add(8); 

        Console.WriteLine();
        foreach (int number in numbers)
        {
            Console.WriteLine(number);
        }

        int answer = numbers.BinarySearch(Lookfor);

        Console.WriteLine("The numbers was found at:");

        Console.WriteLine(answer);

    }
 }
}

如果有人能告诉我如何修改它以计算比较,将不胜感激。

非常感谢,马修。

4

4 回答 4

5

实现一个IComparer<int>计算比较的:

private class CountComparer : IComparer<int> {

  public int Count { get; private set; }

  public CountComparer() {
    Count = 0;
  }

  public int Compare(int x, int y) {
    Count++;
    return x.CompareTo(y);
  }

}

然后在需要比较器的重载BinarySearch中将其用作比较

CountComparer comparer = new CountComparer();
int answer = numbers.BinarySearch(Lookfor, comparer);

然后比较器包含计数:

Console.WriteLine("The binary search made {0} comparisons.", comparer.Count);

奖励:任何可比较类型的通用计数比较器:

private class CountComparer<T> : IComparer<T> where T : IComparable<T> {

  public int Count { get; private set; }

  public CountComparer() {
    Count = 0;
  }

  public int Compare(T x, T y) {
    Count++;
    return x.CompareTo(y);
  }

}
于 2012-10-05T08:19:51.907 回答
3

您可以编写一个自定义IComparer<int>来计算它的使用次数,然后在您的搜索方法中使用它。(或者IEqualityComparer<int>我想你的线性搜索的自定义。)

于 2012-10-05T08:17:47.580 回答
3

您可以使用此扩展方法(基于此答案的代码)

public static class ListEx
{
    public static Tuple<int, int> BinarySearchWithCount<T>(
        this IList<T> list, T key)
    {
        int min = 0;
        int max = list.Count - 1;
        int counter = 0;

        while (min <= max)
        {
            counter++;
            int mid = (min + max) / 2;
            int comparison = Comparer<T>.Default.Compare(list[mid], key);
            if (comparison == 0)
            {
                return new Tuple<int, int>(mid, counter);
            }
            if (comparison < 0)
            {
                min = mid + 1;
            }
            else
            {
                max = mid - 1;
            }
        }

        return new Tuple<int, int>(~min, counter);
    }
}

//Which returns a tuple with the item and a number of comparisons. 
//Here is how you can use it:

class Program
{
    static void Main(string[] args)
    {
        var numbers = new List<int>();
        numbers.AddRange(Enumerable.Range(0, 100000));

        var answer = numbers.BinarySearchWithCount(2);
        Console.WriteLine("item: " + answer.Item1);   // item: 2
        Console.WriteLine("count: " + answer.Item2);  // count: 15

    }
}
于 2012-10-05T08:39:30.097 回答
0

这是某种家庭作业吗?该List<T>.BinarySearch方法不提供此类信息。

如果您想要比较次数,您要么必须编写自己的IComparer二进制搜索,要么仍然使用 .NET 方法并根据列表的长度和元素的位置计算计数。

于 2012-10-05T08:19:15.803 回答