Javascript 多维数组填充
我试图在多维数组中填充一个区域,但不确定该方法 例如,我有以下数组:Javascript 多维数组填充,javascript,arrays,algorithm,multidimensional-array,flood-fill,Javascript,Arrays,Algorithm,Multidimensional Array,Flood Fill,我试图在多维数组中填充一个区域,但不确定该方法 例如,我有以下数组: var map = [ [0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 2, 2, 2, 2, 2, 2, 0, 0], [0, 2, 0, 0, 0, 0, 2, 0, 0], [0, 2, 0, 2, 0, 0, 2, 0, 0], [0, 2, 0, 0, 2, 0, 2, 0, 0], [0, 0, 2, 0, 0, 0, 2, 0, 0], [
var map = [
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 2, 2, 2, 2, 2, 2, 0, 0],
[0, 2, 0, 0, 0, 0, 2, 0, 0],
[0, 2, 0, 2, 0, 0, 2, 0, 0],
[0, 2, 0, 0, 2, 0, 2, 0, 0],
[0, 0, 2, 0, 0, 0, 2, 0, 0],
[0, 0, 0, 2, 2, 2, 2, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0]
];
var map = [
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 2, 2, 2, 2, 2, 2, 0, 0],
[0, 2, 1, 1, 1, 1, 2, 0, 0],
[0, 2, 1, 2, 1, 1, 2, 0, 0],
[0, 2, 1, 1, 2, 1, 2, 0, 0],
[0, 0, 2, 1, 1, 1, 2, 0, 0],
[0, 0, 0, 2, 2, 2, 2, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0]
];
然后我尝试从X和Y位置获取数字,并用给定的数字(如1)填充所有这些数字(即0),这将产生以下数组:
var map = [
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 2, 2, 2, 2, 2, 2, 0, 0],
[0, 2, 0, 0, 0, 0, 2, 0, 0],
[0, 2, 0, 2, 0, 0, 2, 0, 0],
[0, 2, 0, 0, 2, 0, 2, 0, 0],
[0, 0, 2, 0, 0, 0, 2, 0, 0],
[0, 0, 0, 2, 2, 2, 2, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0]
];
var map = [
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 2, 2, 2, 2, 2, 2, 0, 0],
[0, 2, 1, 1, 1, 1, 2, 0, 0],
[0, 2, 1, 2, 1, 1, 2, 0, 0],
[0, 2, 1, 1, 2, 1, 2, 0, 0],
[0, 0, 2, 1, 1, 1, 2, 0, 0],
[0, 0, 0, 2, 2, 2, 2, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0]
];
基本上只是将该区域内相邻的所有数字(0)替换为(1)
使用JavaScript执行此操作的正确方法是什么?假设给您一个起始位置,然后您希望向上/向下、向左/向右填充包含相同值的所有相邻值,您可以执行以下操作:
var map = [
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 2, 2, 2, 2, 2, 2, 0, 0],
[0, 2, 0, 0, 0, 0, 2, 0, 0],
[0, 2, 0, 2, 0, 0, 2, 0, 0],
[0, 2, 0, 0, 2, 0, 2, 0, 0],
[0, 0, 2, 0, 0, 0, 2, 0, 0],
[0, 0, 0, 2, 2, 2, 2, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0]
];
function fill(data, x, y, newValue) {
// get target value
var target = data[x][y];
function flow(x,y) {
// bounds check what we were passed
if (x >= 0 && x < data.length && y >= 0 && y < data[x].length) {
if (data[x][y] === target) {
data[x][y] = newValue;
flow(x-1, y); // check up
flow(x+1, y); // check down
flow(x, y-1); // check left
flow(x, y+1); // check right
}
}
}
flow(x,y);
}
fill(map, 2, 2, 1);
var映射=[
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 2, 2, 2, 2, 2, 2, 0, 0],
[0, 2, 0, 0, 0, 0, 2, 0, 0],
[0, 2, 0, 2, 0, 0, 2, 0, 0],
[0, 2, 0, 0, 2, 0, 2, 0, 0],
[0, 0, 2, 0, 0, 0, 2, 0, 0],
[0, 0, 0, 2, 2, 2, 2, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0]
];
函数填充(数据、x、y、新值){
//获取目标值
var目标=数据[x][y];
函数流(x,y){
//边界检查我们通过了什么
如果(x>=0&&x=0&&y
工作演示:
这是一个不使用递归的版本,似乎可以处理大型数据集。您的大型测试数据集不是一个非常有趣的测试模式,因此我不会说这是最终测试的,但它似乎对小型和大型数据集都有效: 大数据示例: 小数据示例:(更容易看到结果) 函数填充(数据、x、y、新值){ //获取目标值 var目标=数据[x][y]; //维护要处理的单元格列表 //将起始单元格放入队列中 变量队列=[{x:x,y:y}],项; while(queue.length){ item=queue.shift(); x=项目x; y=项目y; 如果(数据[x][y]==目标){ 数据[x][y]=新值; //向上 如果(x>0){ push({x:x-1,y:y}) } //向下 if(x+1<数据长度){ push({x:x+1,y:y}) } //左 如果(y>0){ push({x:x,y:y-1}); } //对 if(y+1<数据[x].长度){ push({x:x,y:y+1}); } } } }
如果需要,可以通过在将值放入队列之前测试该值,并遵循给定的方向直到找到不匹配的值来进一步优化性能。假设给定了起始位置,然后要向上/向下、左/右填充包含相同值的所有相邻值,您可以这样做:
var map = [
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 2, 2, 2, 2, 2, 2, 0, 0],
[0, 2, 0, 0, 0, 0, 2, 0, 0],
[0, 2, 0, 2, 0, 0, 2, 0, 0],
[0, 2, 0, 0, 2, 0, 2, 0, 0],
[0, 0, 2, 0, 0, 0, 2, 0, 0],
[0, 0, 0, 2, 2, 2, 2, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0]
];
function fill(data, x, y, newValue) {
// get target value
var target = data[x][y];
function flow(x,y) {
// bounds check what we were passed
if (x >= 0 && x < data.length && y >= 0 && y < data[x].length) {
if (data[x][y] === target) {
data[x][y] = newValue;
flow(x-1, y); // check up
flow(x+1, y); // check down
flow(x, y-1); // check left
flow(x, y+1); // check right
}
}
}
flow(x,y);
}
fill(map, 2, 2, 1);
var映射=[
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 2, 2, 2, 2, 2, 2, 0, 0],
[0, 2, 0, 0, 0, 0, 2, 0, 0],
[0, 2, 0, 2, 0, 0, 2, 0, 0],
[0, 2, 0, 0, 2, 0, 2, 0, 0],
[0, 0, 2, 0, 0, 0, 2, 0, 0],
[0, 0, 0, 2, 2, 2, 2, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0]
];
函数填充(数据、x、y、新值){
//获取目标值
var目标=数据[x][y];
函数流(x,y){
//边界检查我们通过了什么
如果(x>=0&&x=0&&y
工作演示:
这是一个不使用递归的版本,似乎可以处理大型数据集。您的大型测试数据集不是一个非常有趣的测试模式,因此我不会说这是最终测试的,但它似乎对小型和大型数据集都有效: 大数据示例: 小数据示例:(更容易看到结果) 函数填充(数据、x、y、新值){ //获取目标值 var目标=数据[x][y]; //维护要处理的单元格列表 //将起始单元格放入队列中 变量队列=[{x:x,y:y}],项; while(queue.length){ item=queue.shift(); x=项目x; y=项目y; 如果(数据[x][y]==目标){ 数据[x][y]=新值; //向上 如果(x>0){ push({x:x-1,y:y}) } //向下 if(x+1<数据长度){ push({x:x+1,y:y}) } //左 如果(y>0){ push({x:x,y:y-1}); } //对 if(y+1<数据[x].长度){ push({x:x,y:y+1}); } } } } 如果需要,可以通过在将值放入队列之前测试该值,并遵循给定的方向直到找到不匹配的值,从而进一步优化该值的性能。这是一个(基于队列的)粗略转换,没有执行优化。还有其他的 Javascript
var map = [
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 2, 2, 2, 2, 2, 2, 0, 0],
[0, 2, 0, 0, 0, 0, 2, 0, 0],
[0, 2, 0, 2, 0, 0, 2, 0, 0],
[0, 2, 0, 0, 2, 0, 2, 0, 0],
[0, 0, 2, 0, 0, 0, 2, 0, 0],
[0, 0, 0, 2, 2, 2, 2, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0]
];
/*
1. Set Q to the empty queue.
2. If the color of node is not equal to target-color, return.
3. Add node to Q.
4. For each element N of Q:
5. If the color of N is equal to target-color:
6. Set w and e equal to N.
7. Move w to the west until the color of the node to the west of w no longer matches target-color.
8. Move e to the east until the color of the node to the east of e no longer matches target-color.
9. For each node n between w and e:
10. Set the color of n to replacement-color.
11. If the color of the node to the north of n is target-color, add that node to Q.
12. If the color of the node to the south of n is target-color, add that node to Q.
13. Continue looping until Q is exhausted.
14. Return.
*/
function floodFill(data, node, targetValue, replacementValue) {
var Q;
if (data[node[0]][node[1]] === targetValue) {
Q = [node];
while (Q.length) {
var N = Q.shift(),
value,
index,
n,
e,
s,
w;
if (data.hasOwnProperty([N[0]]) && data[N[0]][N[1]] === targetValue) {
w = e = N[0];
do {
w -= 1;
} while (data.hasOwnProperty(w) && data[w][N[1]] === targetValue);
do {
e += 1;
} while (data.hasOwnProperty(e) && data[e][N[1]] === targetValue);
n = N[1] - 1;
s = N[1] + 1;
for (index = w + 1; index < e; index += 1) {
data[index][N[1]] = replacementValue;
if (data[index].hasOwnProperty(n) && data[index][n] === targetValue) {
Q.push([index, n]);
}
if (data[index].hasOwnProperty(s) && data[index][s] === targetValue) {
Q.push([index, s]);
}
}
}
}
}
}
floodFill(map, [2, 2], 0, 1);
map.forEach(function (m) {
console.log(JSON.stringify(m));
});
var映射=[
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 2, 2, 2, 2, 2, 2, 0, 0],
[0, 2, 0, 0, 0, 0, 2, 0, 0],
[0, 2, 0, 2, 0, 0, 2, 0, 0],
[0, 2, 0, 0, 2, 0, 2, 0, 0],
[0, 0, 2, 0, 0, 0, 2, 0, 0],
[0, 0, 0, 2, 2, 2, 2, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0]
];
/*
1.将Q设置为空队列。
2.如果节点的颜色不等于目标颜色,则返回。
3.将节点添加到Q。
4.对于Q的每个元素N:
5.如果N的颜色等于目标颜色:
6.