【问题标题】:Alternative for SortedSet<T> in Portable Class Library?可移植类库中 SortedSet<T> 的替代方案?
【发布时间】:2014-09-22 14:02:47
【问题描述】:

SortedSet&lt;T&gt; 在 PCL 中是否有替代方案?还是我必须自己实现?

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

【问题讨论】:

  • 如果你去newer version of the documentation你会发现支持PCL/Windows Phone/Windows Store。
  • @PatrykĆwiek 感谢您指出这一点。但是我需要支持 .NET 4.0。我更新了问题。
  • 哦,对不起。据我所知,你很不走运,你要么必须使用第三方解决方案,要么推出自己的实施......
  • 你需要一个set吗?或者,您只是在寻找排序后的集合?
  • @PeterRitchie 我确实想要一个已排序的集合,这样我就可以对其进行快速、高效的搜索。该列表也不得包含重复项。

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


【解决方案1】:

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

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)...

还有其他可能更快的算法;但没有更多内容可做,我选择了一个简单且易于理解的算法。

【讨论】:

  • FWIW,重命名为SortedCollection,因为它没有实现ISet&lt;T&gt;(也不能实现)
猜你喜欢
  • 2013-08-24
  • 2018-10-14
  • 1970-01-01
  • 2012-10-05
  • 2015-08-05
  • 2010-12-19
  • 2010-11-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多