У меня есть матрица 0s и 1s, и мне нужно извлечь «фигуры» из этой матрицы. Формы состоят из 1s, соединенных в 8 направлениях. В конечном результате я получаю 2d массив фигур. Каждый массив форм содержит индексы клеток в исходной матрице. Я написал скрипт, и он работает, за исключением того, что он падает с большими матрицами. И я получаю ошибку в консоли Uncaught RangeError: Maximum call stack size exceeded
Мне нужно, чтобы она работала с большими матрицами, такими как 1000 x 1000 и более.Оптимизация алгоритма определения формы
Вот мой код:
var matrixCols = 150;
var matrixRows = 150;
var matrix = [];
var shapes = [];
var checkedCels = [];
function createMatrix() {
\t for(var i = 0; i < matrixRows; i++) {
\t var row = [];
\t \t for(var j = 0; j < matrixRows; j++) {
\t var value = Math.round(Math.random());
row.push(value);
\t matrix.push(value);
}
console.log(JSON.stringify(row));
} \t
}
function getShapes() {
\t for(var i = 0; i < matrix.length; i++) {
\t if(checkedCels.indexOf(i) === -1 && matrix[i] === 1) {
\t shapes.push(formShape(i));
}
}
console.log('Total shapes:', shapes.length);
console.log(shapes);
}
function formShape(startIndex) {
\t return getNeighbours(startIndex);
}
function getNeighbours(index) {
\t if(checkedCels.indexOf(index) > -1) {
\t return [];
}
var cels = [index];
checkedCels.push(index);
var nwIndex = index - matrixCols - 1;
var nwCel = matrix[nwIndex];
if(typeof nwCel !== 'undefined' && nwCel === 1 && index % matrixCols > 0) {
\t cels = cels.concat(getNeighbours(nwIndex));
}
var nIndex = index - matrixCols;
var nCel = matrix[nIndex];
if(typeof nCel !== 'undefined' && nCel === 1) {
\t cels = cels.concat(getNeighbours(nIndex));
}
var neIndex = index - matrixCols + 1;
var neCel = matrix[neIndex];
if(typeof neCel !== 'undefined' && neCel === 1 && index % matrixCols < (matrixCols - 1)) {
\t cels = cels.concat(getNeighbours(neIndex));
}
var wIndex = index - 1;
var wCel = matrix[wIndex];
if(typeof wCel !== 'undefined' && wCel === 1 && index % matrixCols > 0) {
\t cels = cels.concat(getNeighbours(wIndex));
}
var eIndex = index + 1;
var eCel = matrix[eIndex];
if(typeof eCel !== 'undefined' && eCel === 1 && index % matrixCols < (matrixCols - 1)) {
\t cels = cels.concat(getNeighbours(eIndex));
}
var swIndex = index + matrixCols - 1;
var swCel = matrix[swIndex];
if(typeof swCel !== 'undefined' && swCel === 1 && index % matrixCols > 0) {
\t cels = cels.concat(getNeighbours(swIndex));
}
var sIndex = index + matrixCols;
var sCel = matrix[sIndex];
if(typeof sCel !== 'undefined' && sCel === 1) {
\t cels = cels.concat(getNeighbours(sIndex));
}
var seIndex = index + matrixCols + 1;
var seCel = matrix[seIndex];
if(typeof seCel !== 'undefined' && seCel === 1 && index % matrixCols < (matrixCols - 1)) {
\t cels = cels.concat(getNeighbours(seIndex));
}
return cels;
}
createMatrix();
getShapes();
Как я могу оптимизировать его?
Опубликовать этот вопрос на http://codereview.stackexchange.com – plasmacel
Javascript не обязательно устраняет хвостовое отклонение, вам нужно будет использовать трюки и батуты или написать нерекурсивную версию. «Оптимизация» на самом деле не проблема ... –
Что вы подразумеваете под словом «use thunks and trampoline»? – Gugis