рекурсивная итеративная хэш-карта - PullRequest
2 голосов
/ 16 марта 2011

Я хочу получить k, v-пар из хэш-карты.записи такие:

a = 3,4 
b = 5,6

и так далее.Мне нужны комбинации этих значений.

a=3, b=5. 
a=3, b=6.
a=4, b=5.
a=4, b=6.

Я не знаю, сколько ключей и сколько записей имеют значения.с entryset я могу получить значения, но не комбинации.это похоже на рекурсию, но как?

Вот мой код:

HashMap<String, String[]> map = new HashMap<String, String[]>();

BufferedReader file = new BufferedReader(new FileReader("test.txt"));
String str;


while ((str = file.readLine()) != null) { 


    ... logic


    map.put(key, value);



}
System.out.println("number of keys: " + map.size());
for(Entry<String, String[]> entry : map.entrySet()) {
    for(String value : entry.getValue()) {
        System.out.println(entry.getKey() + ": " + value);
    }
}
file.close();

Ответы [ 2 ]

5 голосов
/ 16 марта 2011

Вы можете попробовать следующий код:

public void mapPermute(Map<String, String[]> map, String currentPermutation) {
    String key = map.keySet().iterator().next(); // get the topmost key

    // base case
    if (map.size() == 1) {          
        for (String value : map.get(key)) {
            System.out.println(currentPermutation + key + "=" + value);
        }
    } else {
        // recursive case
        Map<String, String[]> subMap = new HashMap<String, String[]>(map);

        for (String value : subMap.remove(key)) {
            mapPermute(subMap, currentPermutation + key + "=" + value + ", ");
        }
    }
}

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

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

0 голосов
/ 16 марта 2011

Похоже, вы действительно хотите MultiMap .В частности, ArrayListMultimap позволяет дублировать записи:

ArrayListMultimap<String, String> map = ArrayListMultimap.create();

for each line in file:
   parse key k
   for each value in line:
      parse value v
      map.put(k, v);

for (Map.Entry<String,String> entry : map.entries()) {
   String key = entry.getKey();
   String value = entry.getValue();
}

Если вы хотите получить декартово произведение карт, вы можете вычислить это непосредственно с помощью рекурсии, или вы можете перебирать карты: создать список итераторов и стиль итерации одометра;когда итератор N достигает своего конца, продвиньте итератор N + 1 и сбросьте итераторы 1..N.


Только что осмотрелся и нашел этот SO вопрос: Итеративное декартово произведение в Java

Поэтому я бы порекомендовал вам использовать Sets.cartesianProduct гуавы для декартового произведения.Вот мой код, который вы можете адаптировать к вашей логике ввода:

    String key1 = "a";
    Set<Integer> values1 = Sets.newLinkedHashSet(Arrays.asList(1, 2, 3, 4 ));
    String key2 = "b";
    Set<Integer> values2 = Sets.newLinkedHashSet(Arrays.asList(5, 6, 7));
    String key3 = "c";
    Set<Integer> values3 = Sets.newLinkedHashSet(Arrays.asList(8, 9));

    List<String> keys = Arrays.asList(key1, key2, key3);
    Set<List<Integer>> product = Sets.cartesianProduct(values1, values2, values3);
    for (List<Integer> values : product) {
        for (int i = 0; i < keys.size(); ++i) {
            String key = keys.get(i);
            int value = values.get(i);
            System.out.print(key + "=" + value + "; ");
        }
        System.out.println();
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...