Как сохранить позиционные индексы и идентификаторы документов в Hashmap - PullRequest
1 голос
/ 13 января 2012

У меня есть текстовые файлы в каталоге. Что мне нужно сделать, это;
--- для каждого слова во всех файлах
--- найти позиционные индексы каждого слова в файле
--- найти каждый файл, который пропустил слово

Для этого

HashMap<String, HashMap<Integer, ArrayList<Integer>>>

Я хочу использовать структуру, как указано выше.

String word;
        String pattern = "[[^\\w\\süÜıİöÖşŞğĞçÇ]\\d]+";
        while ((word = infile.readLine()) != null) {
            String[] wordList = word.replaceAll(pattern, " ").split("\\s+");

            for (int j = 0; j < wordList.length; j++) {
                if(!wordList[j].isEmpty()){
                        if(!refinedDict.containsKey(wordList[j])){
                            refinedDict.put(wordList[j], 1);
                        }
                        else{
                            refinedDict.put(wordList[j], refinedDict.get(wordList[j])+1);
                        }
                    }//end of for
                 }//end if
                else{
                 //do something   
                }
            }//end for
        }//end while

 Set<String> keys=refinedDict.keySet();
 List<String> list=sortList(keys);
 Iterator<String> it=list.iterator();
 while(it.hasNext()){
       String key=it.next();
       outfile.write(key + "\t" + refinedDict.get(key) + "\n");



Как я могу использовать ArrayList в HashMap в HashMap

EDIT
После применения решения toto2 реализация работает. Однако, чтобы записать его в файл как --->
word [fileId {позиции}, fileId {позиции} ...]
Что можно сделать?
Реализация сериализуемого бесполезна для такого дизайна.

Ответы [ 4 ]

1 голос
/ 13 января 2012

Я определяю два новых класса FileId и PositionInFile вместо Integer s для ясности.

Map<String, Map<FileId, List<PositionInFile>>> wordsWithLocations;

for (int j = 0; j < wordList.length; j++) {
   if (!wordList[j].isEmpty()){
      if (!wordsWithLocations.containsKey(wordList[j])) {
         Map<FileId, List<PositionInFile>> map = new HashMap<>();
         List<PositionInFile> list = new ArrayList<>();
         list.add(wordPosition[j]);
         map.put(fileId, list);
         wordsWithLocations.put(wordList[j], map);
       } else {
          Map<FileId, List<PositionInFile>> map = 
                          wordsWithLocation.get(wordList[j]);
          if (map.contains(fileId)) {
             map.get(fileId).add(wordPosition[j]);
          } else {
             List<PositionInFile> list = new ArrayList<>();
             list.add(wordPosition[j]);
             map.put(fileId, list);
          }
       }
    }
}

...

for (String word : wordsWithLocation) {
   int nAppearances = 0;
   for (List<PositionInFile> positions :      
                            wordsWithLocation.get(word).values()) {
      nAppearances += positions.size();
   }
   System.out.println(word + " appears " + nAppearances + " times.");
}

Однако я думаю, что было бы проще и понятнее определить:

public class WordLocation {
   FileId fileId;
   PositionInFile position;

   ... 
}

и тогда просто есть Map<String, List<WordLocation>>. Недостатком является то, что у вас нет такого явного сопоставления с файлами. Однако информация все еще там, и List<WordLocation> должен даже иметь местоположения, перечисленные в том же порядке, что и файлы.

0 голосов
/ 13 января 2012

Не уверен точно.Но вот общий способ, которым я использую для карты, что значение имеет тип коллекции.

Map<String, Collection<something>> map ...
for ... do some job
   if map.containsKey(keyFound) {
      map.get(foundKey).add(foundValue);
   } else {
      Collection <- create collection
      Collection.add(foundValue);
      map.put(foundKey, collection)
   }

Вы также можете проверить мультикарты Google Guava.

0 голосов
/ 13 января 2012

вложенная карта будет работать.однако я бы создал для этого класс, т. е.

class WordsInFile{

String fileName;
Map<String, List<Integer>> wordIdxMap;

}

, что на самом деле не имеет большого значения для вложенных карт.но более читабельным, и вы можете добавить такие методы, как findWord (...) ..., чтобы избежать потери, вызывая дважды методы get (object) карт.Это даст вам знать, что вы собираетесь получить.

Я не знаю, хорошая ли это идея ...

0 голосов
/ 13 января 2012

Предполагая, что ваш HashMap определен, как указано выше, и добавьте следующую запись:

HashMap<String, HashMap<Integer, ArrayList<Integer>>> outer = ...
HashMap<Integer, ArrayList<Integer>> inner = ...
inner.put(1, new ArrayList<Integer>());
outer.put("key1", inner);

, вы можете получить ArrayList как:

ArrayList<Integer> arr = outer.get("key1").get(1);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...