在 C# 中展平数组 [重复]
Posted
技术标签:
【中文标题】在 C# 中展平数组 [重复]【英文标题】:Flatten an Array in C# [duplicate] 【发布时间】:2016-07-30 11:27:46 【问题描述】:在 C# 中,扁平化数组的最短代码是什么?
例如,我想要
[[1,2],[2,3],[4,5]]
进入数组
[1,2,3,4,5]
我正在寻找最短的方法。
【问题讨论】:
***.com/questions/5721360/… 虽然我怀疑这是最有效的做法,但我会创建一个扩展函数来为我做这件事。它将递归循环遍历所有元素和元素中包含的元素,并将它们添加到 List也许我读错了“最短代码”,但我建议使用 LINQ SelectMany
和 Distinct
:
var values = new[]
new[] 1, 2 ,
new[] 2, 3 ,
new[] 4, 5 ,
;
var flattenedUniqueValues = values.SelectMany(x => x).Distinct();
【讨论】:
【参考方案2】:将交错数组转换为一维数组很简单,可以在O(n)
时间和n
空间中完成(其中n
是二维数组长度的总和),但是在您的示例中,您似乎删除了重复值 - 这不是展平数组,但它仍然可以在 O(n)
时间内完成,但需要 O(2n)
空间,因为您需要一个用于 O(1)
重复值查找的哈希表。
提前知道最终数组中将存在多少元素可能存在问题。一个简单的解决方案是附加到List<T>
并在最后调用.ToArray()
,但这将导致O(2n)
时间和O(3n)
空间(但可能更多是由于List<T>
内部重新分配):
Int32[][] jagged = ...
HashSet<Int32> seen = new HashSet<Int32>();
List<Int32> ret = new List<Int32>();
for(int i = 0; i < jagged.Length; i++)
for(int j = 0; j < jagged[i].Length; j++)
Int32 val = jagged[i][j];
if( !seen.Contains( val ) )
ret.Add( val );
seen.Add( val );
return ret.ToArray(); // This takes O(n) time and will allocate O(n) additional space.
另一种解决方案是通过自己执行 2 遍:第一次确定输出的大小,然后第二遍生成它 - 这将减少复制:正好是 O(2n)
时间和正好是 O(2n)
空间:
Int32[][] jagged = ...
HashSet<Int32> seen = new HashSet<Int32>();
// Pass 1
for(int i = 0; i < jagged.Length; i++)
for(int j = 0; j < jagged[i].Length; j++)
Int32 val = jagged[i][j];
seen.Add( val ); // HashSet.Add is safe/idempotent
Int32[] ret = new Int32[ seen.Count ];
// Pass 2
seen.Clear();
Int32 retIdx = 0;
for(int i = 0; i < jagged.Length; i++)
for(int j = 0; j < jagged[i].Length; j++)
Int32 val = jagged[i][j];
if( !seen.Contains( val ) )
ret[++retIdx] = val;
seen.Add( val );
return ret;
【讨论】:
以上是关于在 C# 中展平数组 [重复]的主要内容,如果未能解决你的问题,请参考以下文章