Преобразование 2d-массива в график

Как преобразовать двумерный массив в график. Где каждый элемент массива соединяется со своим соседом (сосед вверх, вниз, вправо и влево).

Предположим, что массив 2x2:

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

График будет такой:

Матрица смежности графа выглядит так:

А Б С Д А 0 1 1 0 Б 1 0 0 1 С 1 0 0 1 Д 0 1 1 0

Список смежности графа выглядит следующим образом:

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

Какой алгоритм для этого понадобится?

Я просто пытаюсь преобразовать 2D-массив в график в JS.

У меня есть класс с именем 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"]
]

Функция, которая может принимать двумерный массив, преобразовывать его в вершины графа и возвращать список вершин. Каждая вершина содержит значение arr и своего соседа. Также список соседей содержит экземпляр Vertex. Например, вершина для элемента «А» выглядит так:

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

Дубликат не допускается. «A» и «D» имеют одинаковых соседей — «B». В этом случае и вершина «A», и вершина «D» содержат один и тот же экземпляр вершины «B».

Как я могу это сделать в js?

пожалуйста, опубликуйте код, который вы пробовали, и опишите проблему, с которой вы столкнулись. Как написано, это запрос на бесплатный код, чего этот сайт не делает, особенно если в вопросе или тегах не указана ни одна платформа кодирования.

teylyn 04.04.2024 01:23

Я разместил свой код. Я не хочу писать полный код, мне просто нужно понять, как я могу это сделать.

Md Tazri 04.04.2024 02:43
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
2
82
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Как вы сказали в комментарии, вам не нужен полный код, я не буду предоставлять полный код, а просто идею простого подхода, как это можно сделать.

  • создайте allvertices: Map<string, Vertex> для хранения всех существующих вершин
  • перебрать весь входной массив

Для каждой вершины во время итерации:

  • получить текущую вершину с карты.

    let v = allvertices.get(vertexname);
    

    это либо вернет вершину, если она уже содержится на карте, либо undefined, если нет.

  • если v — это undefined, создайте v = new Vertex(vertexname) и добавьте его на карту

    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. Если нет, создайте его и добавьте в allvertices (как указано выше)

  • добавьте его в список соседей вершины v

    v.addNeighbour(neighbour);
    

Таким образом, вы создадите ровно один Vertex для каждой записи вашего входного массива, а также ссылки всегда будут идти на один и тот же узел, т.е. у вас не будет дубликатов, как и просили...

Еще один, еще более простой подход, который не требует дополнительной карты (но требует двух итераций входного массива).

  • повторите свой arr один раз и для каждой вершины замените string, который у вас сейчас есть в массиве, на экземпляр класса Vertex

    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);
      }
    }
    

    Вместо создания массива neighbours вы, конечно, также можете выполнить соответствующие проверки, определен ли сосед, и затем добавить его.

    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 находится за пределами границ.

  • И добавьте соседей к текущей вершине (как указано выше)

// Спасибо за это. Обе идеи мне очень помогли.

Md Tazri 04.04.2024 21:54

Другие вопросы по теме