zoukankan      html  css  js  c++  java
  • C# 3.0 CookBook:三、类与结构(3):让类型支持搜索

    问题

        已有一个自定义类型可以像List<T>中的元素那样排序,还要使用BinarySearch方法在该列表对其自定义的类型制定查询规则。

    解决方案

        使用IComparable<T> 和IComparer<T>接口。使用3-1节中的Square类,以List<T>和SortedList<K,V>集合对Square对象实现排序和查询的方法实现IComparable<T>接口。

    讨论

        依靠在用户自定义的类(或结构)中实现IComparable<T>接口,可以得到List<T>和SortedList<K,V>类中一样的搜索算法的优势。在这些类中的内置搜索算法中,用户只需要实现IComparable<T>接口告诉这些类要怎样查找用户自定义类型。

        关于实现CompareTo方法,可参见3-2节

        List<T>类提供了BinarySearch(二分搜索)方法来对列表中的元素进行搜索。每一个元素都会和另一个作为参数传入BinarySearch方法中的元素对象进行比较。SortedList类型没有包含BinarySearch方法,而是用ContainsKey方法进行代替,该方法对列表中包含的键值进行二分搜索。SortedList类中ContainsValue方法则是使用线性搜索法搜索列表中的值。该方法则是调用SortedList集合中的Equals方法来完成搜索。SortedList类中的线性搜索算法在使用Compare和CompareTo方法时没有任何的优越效果,但是它们在二分搜索上使用很有效。

    要使List<T>类型使用BinarySearch方法得到准确的搜索结果,要先调用List<T>方法的Sort方法。此外,如果在BinarySearch方法中使用IComparer<T>接口,必须对Sort方法传递一个一样的接口。否则,BinarySearch方法可能将无法找到目标对象。

        示例3-4中的TestSort方法示范了怎样在List<Square>和SortedList<int,Square>集合的实例中使用Square类和CompareHeight类。

    //示例3-4.让类型支持搜索
    
    public static void TestSearch()
    {
        List<Square> listOfSquares = new List<Square> {new Square(1,3),
                                                       new Square(4,3),
                                                       new Square(2,1),
                                                       new Square(6,1)};
        IComparer<Square> heightCompare = new CompareHeight();
        // Test a List<Square>
        Console.WriteLine("List<Square>");
        Console.WriteLine("Original list");
        foreach (Square square in listOfSquares)
        {
            Console.WriteLine(square.ToString());
        }
        Console.WriteLine();
        Console.WriteLine("Sorted list using IComparer<Square>=heightCompare");
        listOfSquares.Sort(heightCompare);
        foreach (Square square in listOfSquares)
        {
            Console.WriteLine(square.ToString());
        }
        Console.WriteLine();
        Console.WriteLine("Search using IComparer<Square>=heightCompare");
        int found = listOfSquares.BinarySearch(new Square(1, 3), heightCompare);
        Console.WriteLine("Found (1,3): " + found);
        Console.WriteLine();
        Console.WriteLine("Sorted list using IComparable<Square>");
        listOfSquares.Sort();
        foreach (Square square in listOfSquares)
        {
            Console.WriteLine(square.ToString());
        }
        Console.WriteLine("Search using IComparable<Square>");
        found = listOfSquares.BinarySearch(new Square(6, 1)); // Use IComparable
        Console.WriteLine("Found (6,1): " + found);
        // Test a SortedList<Square>
        var sortedListOfSquares = new SortedList<int, Square>(){
                                            {0, new Square(1,3)},
                                            {2, new Square(4,3)},
                                            {1, new Square(2,1)},
                                            {4, new Square(6,1)}};
        Console.WriteLine();
        Console.WriteLine();
        Console.WriteLine("SortedList<Square>");
        foreach (KeyValuePair<int, Square> kvp in sortedListOfSquares)
        {
            Console.WriteLine(kvp.Key + " : " + kvp.Value);
        }
        Console.WriteLine();
        bool foundItem = sortedListOfSquares.ContainsKey(2);
        Console.WriteLine("sortedListOfSquares.ContainsKey(2): " + foundItem);
        // Does not use IComparer or IComparable
        // -- uses a linear search along with the Equals method
        // which has not been overloaded
        Square value = new Square(6, 1);
        foundItem = sortedListOfSquares.ContainsValue(value);
        Console.WriteLine("sortedListOfSquares.ContainsValue(new Square(6,1)): " + foundItem);
    }

        上述代码输出结果如下所示:

    List<Square>
    Original list
    Height:1 Width:3
    Height:4 Width:3
    Height:2 Width:1
    Height:6 Width:1
    Sorted list using IComparer<Square>=heightCompare
    Height:1 Width:3
    Height:2 Width:1
    Height:4 Width:3
    Height:6 Width:1
    Search using IComparer<Square>=heightCompare
    Found (1,3): 0
    Sorted list using IComparable<Square>
    Height:2 Width:1
    Height:1 Width:3
    Height:6 Width:1
    Height:4 Width:3
    Search using IComparable<Square>
    Found (6,1): 2
    SortedList<Square>
    0 : Height:1 Width:3
    1 : Height:2 Width:1
    2 : Height:4 Width:3
    4 : Height:6 Width:1
    sortedListOfSquares.ContainsKey(2): True
    sortedListOfSquares.ContainsValue(new Square(6,1)): True

    还可参见

        3-2节;MSDN文档中“IComparable<T>接口”主题和“IComparer<T>接口”主题。

    版权说明:作者:张颖希PocketZ's Blog
    出处:http://www.cnblogs.com/PocketZ
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

    本文翻译内容取自网络,纯粹是练习英文水平,如有雷同,纯属意外!有不妥之处,欢迎拍砖!

  • 相关阅读:
    从一个小程序跳到另一个小程序的写法
    小程序input组件失焦的使用
    小程序弹框wx.showModal的使用
    小程序在选择某一个东西的时候,可以用if,else 来做
    reverse啥时候可以用
    js中array.some()的用法
    element ui的table的头部自定义
    逻辑表达式
    cookie
    命名
  • 原文地址:https://www.cnblogs.com/PocketZ/p/Making_a_Type_Searchable.html
Copyright © 2011-2022 走看看