c# - 自定义类字符串列表的二进制搜索算法

时间:2016-04-16 11:40:34

标签: c# algorithm list binary-search

基本上我需要帮助调整我的二进制搜索算法来处理我的字符串列表,如下所示。 注意,我必须使用书面二进制搜索算法,不使用内置的c#函数,如.BinarySearch。

我现在将向您展示如何格式化列表以及列表本身:

// This class formats the list, might be useful to know

public class Demo
{
    public string Col;
    public string S1;
    public string S2;
    public string S3;

    public override string ToString()
    {
        return string.Format("Col: {0}, S1: {1}, S2: {2}, S3: {3}", Col, S1, S2, S3);
    }
}

// The list itself

var list = new List<Demo>
        {   
            new Demo {Col = "Blue", S1 ="88", S2 ="Yes"},
            new Demo {Col = "Green", S1 ="43", S2 ="Yes"},
            new Demo {Col = "Red", S1 ="216", S2 ="No"},
            new Demo {Col = "Yellow", S1 ="100", S2 ="No"}
        };

列表已按字母顺序排列为“Col”字符串值,因此Blue为第一个,Yellow为最后一个。 'Col'是需要搜索的列表的一部分。下面我插入了可以搜索int数组的当前二进制搜索。

public static int BinarySearch_R(int key, int[] array, int low, int high)
    {
        if (low > high) return -1;
        int mid = (low + high) / 2;
        if (key == array[mid])
        {

            return mid;
        }
        if (key < array[mid]) {
            return BinarySearch_R(key, array, low, mid - 1);
        } else {
            return BinarySearch_R(key, array, mid + 1, high);
        }
    }

我需要帮助调整我的BinarySearch算法以适用于上面的列表。如果你们有任何问题,或者需要查看更多我的代码,请问。

3 个答案:

答案 0 :(得分:1)

具体答案:根据具体情况调整您的方法非常简单。

首先让您更新现有方法,使用更通用的方法(IComparable<T>.CompareTo进行比较,而不是int运算符:

public static int BinarySearch_R(int key, int[] array, int low, int high)
{
    if (low > high) return -1;
    int mid = (low + high) / 2;
    int compare = key.CompareTo(array[mid]);
    if (compare == 0)
    {
        return mid;
    }
    if (compare < 0)
    {
        return BinarySearch_R(key, array, low, mid - 1);
    }
    else {
        return BinarySearch_R(key, array, mid + 1, high);
    }
}

然后您只需复制/粘贴上述方法,将int key替换为string key,将int[] array替换为List<Demo> array,将array[mid]替换为array[mid].Col }}:

public static int BinarySearch_R(string key, List<Demo> array, int low, int high)
{
    if (low > high) return -1;
    int mid = (low + high) / 2;
    int compare = key.CompareTo(array[mid].Col);
    if (compare == 0)
    {
        return mid;
    }
    if (compare < 0)
    {
        return BinarySearch_R(key, array, low, mid - 1);
    }
    else {
        return BinarySearch_R(key, array, mid + 1, high);
    }
}

扩展答案:虽然您可以执行上述操作,但您需要对您需要此类功能的任何其他属性/类执行相同操作。

更好的方法是概括代码。例如,int[]List<Demo>可以概括为IReadOnlyList<T>int/string keyTKey keyDemo.ColFunc<T, TKey>,{{ 1}}为CompareTo,因此最终的通用方法可能是这样的:

IComparer<TKey>.Compare

现在,您可以将该单一方法用于任何数据结构。例如,通过public static class MyAlgorithms { public static int BinarySearch<T, TKey>(this IReadOnlyList<T> source, Func<T, TKey> keySelector, TKey key, IComparer<TKey> keyComparer = null) { return source.BinarySearch(0, source.Count, keySelector, key, keyComparer); } public static int BinarySearch<T, TKey>(this IReadOnlyList<T> source, int start, int count, Func<T, TKey> keySelector, TKey key, IComparer<TKey> keyComparer = null) { // Argument validations skipped if (keyComparer == null) keyComparer = Comparer<TKey>.Default; int lo = start, hi = start + count - 1; while (lo <= hi) { int mid = lo + (hi - lo) / 2; int compare = keyComparer.Compare(key, keySelector(source[mid])); if (compare < 0) hi = mid - 1; else if (compare > 0) lo = mid + 1; else return mid; } return -1; } } 搜索List<Demo>将是这样的:

Col

答案 1 :(得分:0)

我只在C#中完成了最基本的东西,所以这可能完全没用。我有一个CS 2类的任务,至少它听起来有点类似于你想要但我们使用java。因此我假设您希望按照某个关键字排序的项目列表(“蓝色”,“绿色”等...)。我使用了LinkedList,但没关系。

    class Node {
    String keyword;
    LinkedList<String> records = new LinkedList<>();
    Node left;
    Node right;


    public Node(String keyword, LinkedList<String> records) {
        this.keyword = keyword;
        this.records = records;
    }
}

现在,至少我能说出一个BST按字符串排序和一个按数字排序的唯一真正区别是你需要某种类型的比较方法来查看一个单词是否是&gt;或者&lt;在字母表中。所以这就是我如何执行插入功能:

   /**
 * insert node
 * @param keyword compare it to other strings
 */
public void insert(String keyword, LinkedList<String> records) {
    //create a new Node
    Node n = new Node(keyword, records);
    int result;
    Node current = root;
    Node parent = null;


    //cont. until NULL
    while (current != null) {
        result = current.keyword.compareTo(n.keyword);
        if (result == 0) return;
        else if (result > 0) {
            parent = current;
            current = current.left;
        }
        else if (result < 0) {
            parent = current;
            current = current.right;
        }
    }

    if (parent == null) root = n;
    else {
        result = parent.keyword.compareTo(n.keyword);
        if (result > 0) parent.left = n;

        else if (result < 0) parent.right = n;

    }
}

所以方法“compareTo(...)”如果字符串0中的字符串更高则返回1,如果相同则返回-1,如果更低则返回-1。所以我会,如果我接近得到你要求的东西,那就得到这个方法的C#版本并像往常那样实现BST。

答案 2 :(得分:0)

只需创建make class IComparable并创建自定义CompareTo()方法即可。一旦类继承了IComparable,像sort这样的标准方法就会自动生效。

   public class Demo : IComparable 
    {
        public string Color;
        public int value;
        public Boolean truth;


        public int CompareTo(Demo other)
        {
            int results = 0;
            if (this.Color == other.Color)
            {
                if (this.value == other.value)
                {
                    results = this.truth.CompareTo(other.truth);
                }
                else
                {
                    results = this.value.CompareTo(other.value);
                }
            }
            else
            {
                results = this.Color.CompareTo(other.Color);
            }

            return results;
        }