【问题标题】:How to check if a IEnumerable<T> is sorted?如何检查 IEnumerable<T> 是否已排序?
【发布时间】:2016-09-23 08:12:02
【问题描述】:

如何检查 IEnumerable 是否已排序?

bool IsSorted<T>(IEnumerable<T> enumerable)
{
   ???
}

【问题讨论】:

  • 仅通过枚举它并确保所有项目都井井有条。对于那个 T 应该实现 IComparable。
  • a) 定义排序的含义。 b) 从第一个项目开始,检查它是否相对于下一个项目排序 - 如果是,检查下一个项目与 n+1 项目。继续直到你发现一对乱序(返回 false)或到达末尾(返回 true)
  • 你有没有尝试过?目前还不清楚你被困在哪里。

标签: c# sorting collections


【解决方案1】:

这种方法的一个例子可能是:

static bool IsSorted<T>(IEnumerable<T> enumerable) where T : IComparable<T> {
    T prev = default(T);
    bool prevSet = false;
    foreach (var item in enumerable) {
        if (prevSet && (prev == null || prev.CompareTo(item) > 0))
            return false;
        prev = item;
        prevSet = true;
    }
    return true;
}

适用于大多数内置类型,例如数字或字符串,因为它们实现了 IComparable。

【讨论】:

    【解决方案2】:

    只需检查每个项目不小于前一个:

      public static partial class EnumerableExtensions {
        public static bool IsSorted<T>(this IEnumerable<T> source, 
                                       IComparer<T> comparer = null) {
          if (null == source)
            throw new ArgumentNullException("source");
    
          if (null == comparer)
            comparer = Comparer<T>.Default;
    
          if (null == comparer)
            throw new ArgumentException("No default comparer found.");
    
          T prior = default(T);
          bool first = true;
    
          foreach (var item in source) {
            if (!first && comparer.Compare(prior, item) > 0)
              return false;
    
            first = false;
            prior = item; 
          }
    
          return true;
        }
      }
    

    【讨论】:

    • 您不需要在您的实现中将 T 限制为 IComparable。
    • @Evk:是的,你可以提供一个comparer;如果是IComparable&lt;T&gt;,则可以使用Comparer&lt;T&gt;.Default
    • 我的意思是编译代码不需要“where T: IComparable”。但是最好让它仍然存在,这样调用者就不能在那里传递任何东西。
    • @Evk:终于明白了;)我应该放弃where T:...
    【解决方案3】:

    这会检查升序或降序排序,而不仅仅是升序

       enum SortOrder
        {
            Unknown = 0,
            Ascending = 1,
            Descending = 2
        }
    
        static bool IsSorted<T>(IEnumerable<T> enumerable)
        {
            var enumerator = enumerable.GetEnumerator();
            // Empty Enumerable
            if (!enumerator.MoveNext())
                return true;
            SortOrder order = SortOrder.None;
    
            // First Item
            var last = enumerator.Current;
            while(enumerator.MoveNext())
            { 
                var result = Comparer<T>.Default.Compare(last, enumerator.Current);
    
                switch (order)
                {
                    case SortOrder.Unknown:
    
                        if (result == 0)
                            break;
                        if(result == -1)
                            order = SortOrder.Ascending;
                        else 
                            order = SortOrder.Descending;
    
                        break;
                    case SortOrder.Descending:
                        if (result == -1)
                            return false;
                        break;
                    case SortOrder.Ascending:
                        if (result == 1)
                            return false;
                        break;
                }
                last = enumerator.Current;
    
            }
    
    
            return true;
        }
    

    【讨论】:

      猜你喜欢
      • 2015-08-11
      • 2014-03-07
      • 2018-02-09
      • 2018-12-18
      • 1970-01-01
      • 2015-06-25
      • 2013-08-09
      • 2017-11-20
      • 2012-04-08
      相关资源
      最近更新 更多