多维阵列;JavaScript;算法



详细信息
我正在研究一个处理多维数组的算法。如果有一个零,那么同一列的元素,但后面的数组也将等于零。我希望能够对未归零的项目求和。

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

transposesum函数非常容易(并且很可能存储在个人实用程序库中,因为它们很可能被重用

我们还需要一个sumToFirstZero函数。在这里,我们写了一个递归的例子,它设法掩盖了一点复杂性,因为n ?区别于其他所有情况——我们的两个基本情况——当我们完成了行,因此nundefined,当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));

最新更新