如何将二维数组转换为图形.其中数组的每个元素都与它们的邻居连接(邻居是上、下、右和左).

假设一个2x2数组是:

[
  [A, B]
  [C, D]
]

图表将是这样的:

enter image description here

图的邻接矩阵是这样的:

A B C D
A 0 1 1 0
B 1 0 0 1
C 1 0 0 1
D 0 1 1 0

图的邻接列表是这样的:

A -> B,C
B -> A,D
C -> A,D
D -> B,C

这将需要什么算法?

我只是try 在JS中将2D数组转换为图形.

我有一个叫vertex的类:

class Vertex {
  constructor(value) {
    this.value = value;
    this.neighbors = [];
  }

  /**
   *
   * @param {Vertex} v
   */
  addNeighborsVertex(v) {
    this.neighbors.push(v);
  }
}

例如2D数组:

let arr = [
    ["A","B"],
    ["C","D"]
]

一个可以取二维数组并转换成图形顶点并返回顶点列表的函数.每个顶点都包含了顶点值和它们的邻居.邻居列表也包含顶点的实例.例如,元素"A"的顶点看起来像这样:

{
    value : "A",
    neighbors : [
        instanceOfVertexB,
        instanceOfVertexC
    ]
}

不允许重复."A"和"D"有相同的邻居,也就是"B".在这种情况下,顶点"A"和顶点"D"都持有顶点"B"的相同实例.

如何在js中做到这一点?

推荐答案

正如你在 comments 中所说的,你不想要完整的代码,我不会提供完整的代码,而只是一个简单的方法,如何做到这一点

  • 创建一个allvertices: Map<string, Vertex>用于存储所有现有顶点
  • 遍历整个输入数组

对于迭代时的每个顶点:

  • 从 map 中获取当前顶点.

    let v = allvertices.get(vertexname);
    

    这将返回顶点(如果它已经包含在 map 中)或undefined(如果没有).

  • 如果vundefined,则创建v = new Vertex(vertexname)并将其添加到 map 中

    allvertices.set(vertexname, v);
    
  • 获取当前顶点的全部let neighbours = [arr[row-1][col],arr[row+1][col],arr[row][col-1],arr[row][col+1]]个.在JS中,你不必关心越界索引.返回数组的不存在索引不会抛出错误,而是返回undefined

对于neighbours数组中不是undefined的每个邻居:

  • 看看它是否已经存在于allvertices map 中.如果没有创建并添加到allvertices(如上所述)

  • 将其添加到顶点v的邻居列表中

    v.addNeighbour(neighbour);
    

这样你就可以为输入数组的每个条目创建一个Vertex,而且refuses也会一直go 到同一个 node ,即你不会有重复的,因为你的请求.

另一种更简单的方法,不需要额外的map(但输入数组的两次迭代)

  • arr进行迭代一次,对于每个顶点,用Vertex类的实例替换数组中当前的string

    arr[row][col] = new Vertex(arr[row][col]);
    
  • 第二次迭代arr,并将所有邻居添加到当前顶点,

    let neighbours = [arr[row-1][col],arr[row+1][col],arr[row][col-1],arr[row][col+1]]
    for (let n of neighbours) {
      if (n !== undefined) {
        arr[row][col].addNeighbour(n);
      }
    }
    

    当然,如果定义了一个邻居,您也可以进行相应的判断,然后添加它,

    if (arr[row-1][col]) arr[row][col].addNeighbour(arr[row-1][col]);
    if (arr[row+1][col]) arr[row][col].addNeighbour(arr[row+1][col]);
    ...
    

当然,你也可以只在一次迭代中完成这个任务.

  • 在迭代数组时,判断当前元素是string还是Vertex.如果是string,就用Vertex代替

    if (typeof arr[row][col] === "string")
      arr[row][col] = new Vertex(arr[row][col]);
    
  • 那就为邻居做同样的事

    if (typeof arr[row+1][col] === "string")
      arr[row+1][col] = new Vertex(arr[row+1][col]);
    if (typeof arr[row-1][col] === "string")
      arr[row-1][col] = new Vertex(arr[row-1][col]);
    ...
    

    同样,这里你不需要关心越界索引,因为typeof undefined === "undefined",因此,上述条件将计算为false,因此,如果例如row+1越界,什么也不做.

  • 并将相邻点添加到当前顶点(如上所述)

Javascript相关问答推荐

为什么我的第二个OnClick Isloading值在TEK查询Mutations 查询中不起作用?

橡皮擦完全让画布变成白色

JS生成具有给定数字和幻灯片计数的数组子集

在页面上滚动 timeshift 动垂直滚动条

在这种情况下,如何 for each 元素添加id?

如何修复我的js构建表每当我添加一个额外的列作为它的第一列?

Angular 17—每当一个布尔变量变为真时触发循环轮询,只要它保持为真

在执行异步导入之前判断模块是否已导入()

material UI按钮组样式props 不反射

DOM不自动更新,尽管运行倒计时TS,JS

如何使用JS创建一个明暗功能按钮?

如何用javascript更改元素的宽度和高度?

图表4-堆叠线和条形图之间的填充区域

如何找到带有特定文本和测试ID的div?

如何通过Axios在GraphQL查询中发送数组

用另一个带有类名的div包装元素

如果我的列有条件,我如何呈现图标?

如何正确地在ComponentWillUnmount中卸载状态以避免内存泄漏?

Django模板中未加载JavaScript函数

如何调整下拉内容,使其不与其他元素重叠?