在c#中使用列表进行二进制搜索

时间:2015-08-07 23:48:32

标签: c# algorithm list binary-search

我使用c#WPF开发Windows应用程序。 该应用程序需要一个类如下

public class Limits
{

    public String col1
    {
        get;
        set;
    }


    public String col2
    {
        get;
        set;
    }

    public String col3
    {
        get;
        set;
    }
}

我使用List存储对象,如: -

List myList<Limits> = new List<Limits>();

&#34; myList中&#34;有大约15000个物体。

现在,我想在myList中搜索特定属性。 例如:我想找出col1设置为&#34; abc&#34;的对象。

如何使用二进制搜索来解决此问题?

4 个答案:

答案 0 :(得分:3)

首先,必须在col1属性上对列表进行排序,才能使用二进制搜索。

您需要一个比较col1属性的比较器:

public class LimitsComparer : IComparer<Limits> {

  public int Compare(Limits x, Limits y) {
    return x.col1.CompareTo(y.col1);
  }

}

然后你可以用它来进行二分查找:

int index = myList.BinarySearch(new Limits { col1 = "abc" }, new LimitsComparer());

返回的索引是:

  

如果找到项目,则排序列表中项目的从零开始的索引;   否则,负数是该位的补码   大于项目的下一个元素的索引,如果没有则   更大的元素,Count的按位补码。

您还可以使用Where方法获取具有该属性的对象:

List<Limits> result = myList.Where(x => x.col1 == "abc").ToList();

尽管效率不高,但您仍应考虑这是否是一个更好的解决方案,因为它更容易实现并且提供更易于处理的结果。此外(这可能更重要),即使列表未在col1上排序,它仍然有效。

答案 1 :(得分:2)

你可以使用这样的东西。

myList.Where(i => i.col1 == "abc").ToList();

答案 2 :(得分:0)

除非您明确要使用二进制搜索,否则应使用可用的标准Linq函数。除非您的列表已经排序,否则这可能比二进制排序更有效。

  var myList = new List<Limits> {....}
  var entry = myList.Where(l => l.col1== "abc").FirstOrDefault();
  if(entry == null)
  { // no match found }

如果你真的想要二元搜索,请参考Can LINQ use binary search when the collection is ordered?

答案 3 :(得分:0)

使用密钥存储在哈希表中的字典。 Linq将轻松创建cdictionary。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication41
{
    class Program
    {
        static void Main(string[] args)
        {
            List<Limits> myList = new List<Limits>();

            //dictionary with unique keys
            Dictionary<string, Limits> dict1 = myList.AsEnumerable()
                .GroupBy(x => x.col2, y => y)
                .ToDictionary(x => x.Key, y => y.FirstOrDefault());

            //dictionary with keys having multiple values
            Dictionary<string, List<Limits>> dict2 = myList.AsEnumerable()
                .GroupBy(x => x.col2, y => y)
                .ToDictionary(x => x.Key, y => y.ToList());

            Limits abc = dict1["abc"];

        }
    }
    public class Limits
    {
        public String col1 { get; set; }
        public String col2 { get; set; }
        public String col3 { get; set; }
    }
}