Как поменять местами значения и ключи arrayMap в Java



У меня возникли некоторые проблемы с реверсированием данной карты и сохранением ее реверсированных ключей и значений в другой карте. У меня есть прототип метода следующим образом:



public static Map<String, Set<String>> reverse (Map <String, Set<String>> graph);


Итак, если у меня есть примеры ключей для направленного графа, такие что:



{c -> arraySet{f, e}}
{b -> d}
{a -> arraySet{c, b}}
{d -> g}
{e -> d}
{f -> arraySet{g, d}}


Мне нужно эффективно перевернуть этот граф так, чтобы вместо b - > d у меня был d - > b.



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



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

1014   4  

4 ответов:

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

public static Map<String, Set<String>> reverse (Map <String, Set<String>> graph) {
    Map<String, Set<String>> result = new HashMap<String, Set<String>>();
    for (Map.Entry<String, Set<String>> graphEntry: graph.entrySet()) {
        for (String graphValue: graphEntry.getValue()) {
            Set<String> set = result.get(graphValue);
            if (set == null) {
                set = new HashSet<String>();
                result.put(graphValue, set);
            }
            set.add(graphEntry.getKey());
        }
    }
    return result;
}

Вот фактический, рабочий, актуальный код с использованиемGuava Multimaps:

SetMultimap<Integer, Integer> graph = HashMultimap.create();
graph.put(1, 2); // add an edge from 1 to 2
SetMultimap<Integer, Integer> inverse = Multimaps.invertFrom(
  graph, HashMultimap.<Integer, Integer> create());

(раскрытие: я делаю вклад в гуаву.)

Но если вы не можете использовать сторонние библиотеки, сделайте что-нибудь вроде этого...
Map<Integer, Set<Integer>> g;
Map<Integer, Set<Integer>> gInverse = new HashMap<Integer, Set<Integer>>();
for (Map.Entry<Integer, Set<Integer>> gAdj : g.entrySet()) {
  Integer v = gAdj.getKey();
  for (Integer w : gAdj.getValue()) {
    Set<Integer> wInverseAdj = gInverse.get(w);
    if (wInverseAdj == null) {
      gInverse.put(w, wInverseAdj = new HashSet<Integer>());
    }
    wInverseAdj.add(v);
  }
}

Или, если вы можете использовать Java 8, используйте это...

map.entrySet().stream()
   .flatMap(entryKToVs -> entryKToVs.getValue().stream()
       .map(v -> new AbstractMap.SimpleEntry<>(entryKToVs.getKey(), str)))
   .collect(groupingBy(Map.Entry::getValue, mapping(Map.Entry::getKey, toList())))

Псевдокод, но близкий к реальному. Просто используйте Multimap .

Multimap<String, String> ret = Multimaps.newSetMultimap();
for (Entry<String, Set<String>> entry : graph) {
  for(String neighbor : entry.getValue()) {
    ret.addTo(neighbor, entry.getKey());
  }
}

Я бы сначала предложил написать класс Graph, который абстрагирует основную структуру данных Map. Конечно, это просто подталкивает реализацию к интерфейсу Graph, а не непосредственно к интерфейсу Map.

Так что пока придерживайтесь своей карты:

Map<String, Set<String>> graph;
Map<String, Set<String>> reverse;

Я предлагаю использовать карту.entrySet () , чтобы получить набор записей из вашего graph. Затем для каждой карты .Запись , получить ключ и значение каждого из них. Далее, для каждой "вершины" в значении Set, вставьте ключ в Set, который связан с вершиной.

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

Comments

    Ничего не найдено.