获取序列的所有子序列

时间:2019-05-08 18:28:53

标签: c# linq

我有一个数组,我需要所有可能的子数组(段或子序列),但空数组除外。这是 不是幂集 ,因为每个子数组仅具有在输入数组中连续的元素。

例如,对于输入new int[]{1,2,3},输出将为:

 new int[]{
   new int[]{1},
   new int[]{1,2},
   new int[]{1,2,3},
   new int[]{2},
   new int[]{2,3},
   new int[]{3}
 }

请注意,{1,3}不存在,因为我不希望所有子集(幂集),而是所有子序列。

我希望使用单个LINQ语句的解决方案。

2 个答案:

答案 0 :(得分:4)

假设您的来源是List(如果不是,请转换为List),您可以这样做:

var srcl = src.ToList();
var ans = Enumerable.Range(0, srcl.Count).SelectMany(start => Enumerable.Range(1, srcl.Count-start).Select(count => srcl.GetRange(start, count)));

使用自然的ArraySegment扩展名:

public static class ArrayExt {
    public static IEnumerable<T> Segment<T>(this T[] src, int start, int count) => new ArraySegment<T>(src, start, count);
}

您可以让它返回一个数组数组:

var ans = Enumerable.Range(0, src.Length).SelectMany(start => Enumerable.Range(1, src.Length-start).Select(count => src.Segment(start, count).ToArray()));

但是通常首选List

答案 1 :(得分:0)

尽管NetMage的解决方案是正确的,但最终我编写了自己的扩展方法,该方法使用Array.Copy来提高性能:

/// <summary>
/// Get all subsequences of the given sequence.
/// {1,2,3}=>{{1,2},{1,2,3},{2,3}}
/// </summary>
public static T[][] GetAllSubsequences<T>(this IEnumerable<T> collection)
{
    var list = (collection as T[]) ?? collection.ToArray();
    return list.SelectMany((x, i) => list.Skip(i).Select((z, j) =>
          {
              var arr = new T[j + 1];
              Array.Copy(list, i, arr, 0, j + 1);
              return arr;
          })).ToArray();
}