javascript - 在 JS 中以最干净和最紧凑的方式在所有可能的方向上对角迭代矩阵
问题描述
因此,我正在尝试编写一个函数,该函数可以通过可配置的从左到右或从右到左迭代对角线迭代任何矩阵(方形或非方形),矩阵沿着对角线迭代,从上到下或从下到上迭代。我确实想出了一个函数,它成功地从左到右、从下到上沿任一对角线迭代矩阵
function iterateDiagonally(matrix, main, rightToLeft, topToBottom)
{
for(let a = 0, b = matrix.length + matrix[0].length - 1; a < b; ++a)
{
let x = main ? Math.min(a, matrix.length - 1) : Math.max(0, a - matrix[0].length + 1);
let y = main ? Math.min(matrix[0].length - 1, matrix.length + 1 - a) : Math.min(a, matrix[0].length - 1);
for(let c = 0, d = Math.min(y + 1, main ? x + 1 : matrix.length - x); c < d; ++c)
{
let eX = main ? x - c : x + c;
let eY = y - c;
console.log(matrix[eX][eY]);
}
}
}
/*
1 4 7
2 5 8
3 6 9
*/
console.log("Along the main diagonal");
iterateDiagonally([[1, 2, 3], [4, 5, 6], [7, 8, 9]], true);
console.log("Along the antidiagonal");
iterateDiagonally([[1, 2, 3], [4, 5, 6], [7, 8, 9]], false);
但意识到也使前 2 个参数变量会使(已经很庞大的代码)看起来更庞大。因此,我正在寻找一种更干净、更紧凑且效率不低的解决方案。谢谢!
解决方案
所以经过深思熟虑,我最终自己完成了它。如果有人遇到同样的问题,请留在这里。它可能看起来很复杂,但想法真的很简单
function iterateDiagonally(matrix, main, rightToLeft, topToBottom)
{
// Move along half of the perimeter, excluding the duplicate corner element
// a - first element of each diagonal
// b - amount of diagonals in total
for(let a = 0, b = matrix.length + matrix[0].length - 1; a < b; ++a)
{
// For the main diagonal, first move right along the x axis starting with the bottom left element, then move up the y axis
// For the antidiagonal, first move down the y axis starting with the top left element, then move right along the x axis
let x = main ? Math.min(a, matrix.length - 1) : Math.max(0, a - matrix[0].length + 1);
let y = main ? Math.min(matrix[0].length - 1, matrix.length + 1 - a) : Math.min(a, matrix[0].length - 1);
// Invert the starting position and direction of all movement
if(rightToLeft) x = matrix.length - 1 - x, y = matrix[0].length - 1 - y;
let diagonal = [];
// Move along each diagonal
// c - element of diagonal
// d - amount of elements in diagonal in total
for(let c = 0, d = Math.min(rightToLeft ? matrix[0].length - y : y + 1, main !== rightToLeft ? x + 1 : matrix.length - x); c < d; ++c)
{
// Invert the diagonal traversal order
let iC = topToBottom !== rightToLeft ? d - 1 - c : c;
// X coordinate of the element
let eX = main !== rightToLeft ? x - iC : x + iC;
// Y coordinate of the element
let eY = rightToLeft ? y + iC : y - iC;
diagonal.push(matrix[eX][eY]);
}
console.log(diagonal.join(", "));
}
}
/*
1 4 7
2 5 8
3 6 9
*/
console.log("Parallel main diagonal, left to right, bottom to top");
iterateDiagonally([[1, 2, 3], [4, 5, 6], [7, 8, 9]], true, false, false);
console.log("Parallel main diagonal, right to left, bottom to top");
iterateDiagonally([[1, 2, 3], [4, 5, 6], [7, 8, 9]], true, true, false);
console.log("Parallel main diagonal, left to right, top to bottom");
iterateDiagonally([[1, 2, 3], [4, 5, 6], [7, 8, 9]], true, false, true);
console.log("Parallel main diagonal, right to left, top to bottom");
iterateDiagonally([[1, 2, 3], [4, 5, 6], [7, 8, 9]], true, true, true);
console.log("Parallel antidiagonal, left to right, bottom to top");
iterateDiagonally([[1, 2, 3], [4, 5, 6], [7, 8, 9]], false, false, false);
console.log("Parallel antidiagonal, right to left, bottom to top");
iterateDiagonally([[1, 2, 3], [4, 5, 6], [7, 8, 9]], false, true, false);
console.log("Parallel antidiagonal, left to right, top to bottom");
iterateDiagonally([[1, 2, 3], [4, 5, 6], [7, 8, 9]], false, false, true);
console.log("Parallel antidiagonal, right to left, top to bottom");
iterateDiagonally([[1, 2, 3], [4, 5, 6], [7, 8, 9]], false, true, true);
推荐阅读
- amazon-web-services - 如何在 Dynamodb 中定义属性类型?
- asp.net - IIS 上带有哈希密码问题的 ASP MVC 登录
- mysql - 如何在 MYSQL 5.7 中为不同的通道设置不同的 replication_do_db?
- tensorflow - 可以在tensorflow中使用Intel Xeon CPU训练深度学习模型,解决gpu内存不足的问题
- angular - 如何使用 HostBinding 定位自定义指令以传递成功或错误消息并显示它?
- javascript - 如何在不渲染的情况下将虚拟 DOM 转换为真实的 DOM 元素?
- react-native - ListItem 头像不显示
- docker - cURL Docker 注册表授权错误“需要身份验证”
- c++ - 从已传递给函数的数组中复制
- python - 合并间隔和时间戳数据帧