如何解决多维数组; JavaScript;算法
详情
我正在研究处理多维数组的算法。如果有一个零,那么同一列的元素,但后面的数组也将等于零。我希望能够对未清零的项目求和。
Example:
matrix = [[0,1,2],[0,5,0],[2,3,3]] --->2,and 3 will not be counted since there is a zero above it.
the output should be: 1+1+2+5 = 9
我目前的工作
function matrixElementsSum(matrix) {
var sum = 0;
for(var i=0;i<matrix.length;i++){
console.log(matrix[i])
for(var j=0;j<=matrix.length;j++){
console.log(matrix[i][j])
if(matrix[i][j] == 0){
console.log(true)
//------------>Here is my problem
}
else {
console.log(false)
}
if(matrix[i][j] !== 0){
sum+=matrix[i][j];
}
}
}
return sum;
}
我想用这个:
matrix[i+1][j] = 0;
但我收到此错误:
TypeError: Cannot read property '1' of undefined
有人可以帮助我理解为什么我的思维过程不起作用以及有什么建议可以继续吗?
谢谢!
解决方法
使用 Javascript 处理矩阵中的行通常比处理列容易得多。因此,一种简洁的书写方式是首先转置矩阵(将其翻转到西北-东南对角线上),然后对每一行求和,直到达到零,最后对这些结果求和。
[
[ 0,5 ],// => 0 = 0
[ 1,5,0 ],// => 1 + 5 = 6
[ 1,3 ],// => 1 = 1
[ 2,// => 2 = 2
] // +__
// 9
transpose
和 sum
函数非常容易(并且很可能存储在个人实用程序库中,因为它们很可能会被重用。
我们还需要一个 sumToFirstZero
函数。在这里,我们编写了一个递归的,它设法隐藏了一点复杂性,因为 n ?
与我们的两个基本情况的其他一切都不同 - 当我们完成了行,因此 n
是 undefined
,并且当 n
为零时。在任何一种情况下,我们都只需返回 0
。在其他情况下,我们将当前值添加到对数组剩余部分的递归调用中。
main 函数只是将这三者放在一起。
const transpose = (xs) =>
xs [0] .map ((_,i) => xs .map (r => r[i]))
const sum = (ns) =>
ns .reduce ((a,b) => a + b,0)
const sumToFirstZero = ([n,...ns]) =>
n ? n + sumToFirstZero (ns) : 0
const problem = (matrix) =>
sum (transpose (matrix) .map (sumToFirstZero))
console .log (problem ([
[0,1,2],[0,0],[2,3,3]
]))
为了清楚说明 sumToFirstZero
如何隐藏一些复杂性,这将是同一函数的逻辑上更清晰的版本:
const sumToFirstZero = ([n,...ns]) =>
n == undefined
? 0
: n == 0
? 0
: n + sumToFirstZero (ns)
但是由于 n
必须是数字或 undefined
,如果我们在递归上触底,我们可以利用 JS 的布尔强制转换 (! n) ? 0 : n + sumToFirstZero (ns)
,或者,就像我们上面所做的那样与n ? n + sumToFirstZero (ns) : 0
当然,我们不必对(转置的)行执行此操作。我们可以直接处理列,摆弄数组参数。但我觉得这要简单得多。
,试试这个代码
const mat1 = [[0,3]]
function matrixElementsSum(matrix) {
for (let i = 0; i < matrix.length; i++) {
const row = matrix[i]
for (let j = 0; j < row.length; j++) {
if (matrix[i][j] === 0) {
for (let k = i; k < matrix.length; k++) {
matrix[k][j] = 0
}
}
}
}
let total = 0
for (let i of matrix)
for (let j of i)
total += j;
return total;
}
console.log(matrixElementsSum(mat1));
如果您不想在算法过程中修改矩阵,那么一种解决方案是为每一列设置标志来指示您是否已经在该列中遇到了 0:
function matrixElementsSum(matrix) {
let sum = 0;
let flags = Array(matrix[0].length).fill(true);
for (let row of matrix) {
for (let j = 0; j < flags.length; j++) {
if (flags[j] &&= row[j]) sum += row[j];
}
}
return sum;
}
let matrix = [[0,3]];
console.log(matrixElementsSum(matrix));
请注意,您在 j
上的循环应具有条件 j < matrix[0].length
如果您的 IDE 抱怨 if
条件中的分配,那么您可以选择将分配与条件分开:
flags[j] &&= row[j];
if (flags[j]) sum += row[j];
或者,如果您不支持此运算符:
flags[j] = flags[j] && row[j];
if (flags[j]) sum += row[j];
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。