如何解决使用LINQ将2D网格变成“菱形”-可能吗?
| 前几天,我需要一种算法来将2D网格变成菱形(通过有效旋转45度),因此我可以将对角序列作为平面枚举来处理,如下所示: 1 2 3 1
4 5 6 => 4 2
7 8 9 7 5 3
8 6
9
我的算法如下:
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;
}
可以使用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)
);
}
输出:
1
4,2
7,5,3
8,6
9
如果您可以假设IList<T>
而不是5 gets,那么这会变得更加整洁和性能更高。我正在考虑一种更有效的方法(不使用.ElementAt
),该方法也可以与IEnumerable`一起使用,如果设法编写,我会发布。
更新:
这是我更实用的版本,仍然可以用相当数量的linq拔尖头。这是一种相当有效的算法,因为它仅对每个“ 7”创建一个枚举器。
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;
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。