详细信息
我正在研究一个处理多维数组的算法。如果有一个零,那么同一列的元素,但后面的数组也将等于零。我希望能够对未归零的项目求和。
Example:
matrix = [[0, 1, 1, 2],
[0, 5, 0, 0],
[2, 0, 3, 3]] --->2, 3, 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, 0, 5 ], // => 0 = 0
[ 1, 5, 0 ], // => 1 + 5 = 6
[ 1, 0, 3 ], // => 1 = 1
[ 2, 0, 3 ], // => 2 = 2
] // +__
// 9
transpose
和sum
函数非常容易(并且很可能存储在个人实用程序库中,因为它们很可能被重用
我们还需要一个sumToFirstZero
函数。在这里,我们写了一个递归的例子,它设法掩盖了一点复杂性,因为n ?
区别于其他所有情况——我们的两个基本情况——当我们完成了行,因此n
是undefined
,当n
是零时。在这两种情况中,我们都只返回0
。在其他情况下,我们将当前值添加到对数组剩余部分的递归调用中。
主要功能只是将这三个组合在一起。
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, 1, 2],
[0, 5, 0, 0],
[2, 0, 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
所做的那样
当然,我们不需要对(转置的(行执行此操作。我们可以直接处理列,篡改数组参数。但我发现这要简单得多。
如果你不想在算法中修改矩阵,那么一个解决方案是为每列设置标志,指示你是否已经在该列中遇到了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, 1, 1, 2],
[0, 5, 0, 0],
[2, 0, 3, 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];
试试这个代码
const mat1 = [[0, 1, 1, 2], [0, 5, 0, 0], [2, 0, 3, 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));