可移植类库中SortedSet <t>的替代方法?</t>

时间:2014-09-22 14:02:48

标签: c# .net sorting portable-class-library

SortedSet<T>的PCL有其他替代方案吗?或者我必须实现自己的吗?

我需要一个非重复字符串的索引列表,我可以在支持.NET 4.0的PCL中搜索。我目前的解决方法是依赖List<T>对象,调用其Sort方法并使用BinarySearch方法。它有效,但我希望我能做得更好。

1 个答案:

答案 0 :(得分:2)

该PCL配置文件中没有“已排序”的集合。因此,您必须在另一个集合上调用Sort方法来对其进行排序或编写您自己的已排序集合。如果您只需要一个集合,则可以使用简单的二进制搜索/插入对项目添加到集合中进行排序。使用支持List<T>的示例可能如下所示:

public class SortedCollection<T> : ICollection<T>
{
    private readonly List<T> collection = new List<T>();
    // TODO: initializable:
    private readonly IComparer<T> comparer = Comparer<T>.Default;

    public void Add(T item)
    {
        if (Count == 0)
        {
            collection.Add(item);
            return;
        }
        int minimum = 0;
        int maximum = collection.Count - 1;

        while (minimum <= maximum)
        {
            int midPoint = (minimum + maximum) / 2;
            int comparison = comparer.Compare(collection[midPoint], item);
            if (comparison == 0)
            {
                return; // already in the list, do nothing
            }
            if (comparison < 0)
            {
                minimum = midPoint + 1;
            }
            else
            {
                maximum = midPoint - 1;
            }
        }
        collection.Insert(minimum, item);
    }

    public bool Contains(T item)
    {
        // TODO: potential optimization
        return collection.Contains(item);
    }

    public bool Remove(T item)
    {
        // TODO: potential optimization
        return collection.Remove(item);
    }

    public IEnumerator<T> GetEnumerator()
    {
        return collection.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }

    public void Clear()
    {
        collection.Clear();
    }

    public void CopyTo(T[] array, int arrayIndex)
    {
        collection.CopyTo(array, arrayIndex);
    }

    public int Count { get { return collection.Count; } }
    public bool IsReadOnly { get { return false; } }
}

我已经完成了最小化以获得有效的已排序集合。您可以进行优化,以便ContainsRemove识别列表已排序并执行O(log n)搜索而不是O(n)......

还有其他算法可能更快;但是,如果没有更多的东西继续下去,我选择了一个简单易懂的算法。