前几天我需要一个算法将2D网格转换为菱形(通过有效旋转45度),所以我可以将对角线序列作为平面枚举处理,如下所示:
1 2 3 1
4 5 6 => 4 2
7 8 9 7 5 3
8 6
9
Run Code Online (Sandbox Code Playgroud)
我的算法如下:
public static IEnumerable<IEnumerable<T>> RotateGrid<T>(IEnumerable<IEnumerable<T>> grid)
{
int bound = grid.Count() - 1;
int upperLimit = 0;
int lowerLimit = 0;
Collection<Collection<T>> rotated = new Collection<Collection<T>>();
for (int i = 0; i <= (bound * 2); i++)
{
Collection<T> row = new Collection<T>();
for (int j = upperLimit, k = lowerLimit; j >= lowerLimit || k <= upperLimit; j--, k++)
{
row.Add(grid.ElementAt(j).ElementAt(k));
}
rotated.Add(row);
if (upperLimit == bound)
lowerLimit++;
if (upperLimit < bound)
upperLimit++;
}
return rotated;
}
Run Code Online (Sandbox Code Playgroud)
可以使用LINQ以更简洁的格式实现吗?
..甚至只是一个更简洁的格式?:)
这是我想出的:
void Main()
{
var lists = new string[] { "123", "456", "789" };
foreach (var seq in RotateGrid(lists))
Console.WriteLine(string.Join(", ", seq));
}
public IEnumerable<IEnumerable<T>> RotateGrid<T>(IEnumerable<IEnumerable<T>> grid)
{
int rows = grid.Count();
int cols = grid.First().Count();
return
from i in Enumerable.Range(0, rows + cols - 1)
select (
from j in Enumerable.Range(0, i + 1)
where i - j < rows && j < cols
select grid.ElementAt(i - j).ElementAt(j)
);
}
Run Code Online (Sandbox Code Playgroud)
输出:
1
4, 2
7, 5, 3
8, 6
9
Run Code Online (Sandbox Code Playgroud)
如果你可以假设IList<T>
s而不是公正,那么这将变得更加清洁和更高效IEnumerable<T>
.我正在考虑一种更有效的方法(不使用.ElementAt
),它也适用于IEnumerable`,如果我设法编写它,我将发布.
更新:
这是我的更实用的版本,仍然设法在相当数量的linq鞋拔.这是一种相当有效的算法,因为它只为每个算法创建一次枚举器IEnumerable
.
public IEnumerable<IEnumerable<T>> RotateGrid<T>(IEnumerable<IEnumerable<T>> grid)
{
var enumerators = new LinkedList<IEnumerator<T>>();
var diagonal =
from e in enumerators
where e.MoveNext()
select e.Current;
foreach (var row in grid)
{
enumerators.AddFirst(row.GetEnumerator());
yield return diagonal.ToArray();
}
T[] output;
while (true)
{
output = diagonal.ToArray();
if(output.Length == 0) yield break;
yield return output;
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
256 次 |
最近记录: |