2015-04-15 5 views
1

Я пытаюсь считать пары слов в текстовом файле. Моя цель - сопоставить каждое слово в строке со словом, которое следует за ним, и затем подсчитать повторяющиеся пары ключ/значение. Меня не интересует заказ. В моем коде в настоящее время используется HashMap для хранения каждой пары слов, но с помощью HashMap я теряю дубликаты записей. Если в моем текстовом файле: "FIRST SECOND THIRD FIRST SECOND", я получу для моего вывода: FIRST [SECOND] SECOND[] THIRD [FIRST]. Поэтому, если у меня есть повторяющийся ключ, следующее строковое значение перезаписывает то, что было раньше. Брэндон Линг помог мне раньше на предыдущем посту, однако я не был ясно с ним по моей цели. Теперь я наконец понял, что HashMap может не работать.
Любая помощь будет оценена по достоинству.Какая структура данных для подсчета пар слов в Java?

import java.io.File; 
import java.io.FileInputStream; 
import java.io.InputStream; 
import java.io.FileNotFoundException; 
import java.util.Iterator; 
import java.util.Scanner; 
import java.util.HashMap; 
import java.util.List; 
import java.util.Map; 
import java.util.Map.Entry; 
import java.util.ArrayList; 
import java.util.Set; 
import java.util.TreeMap; 



public class Assignment1 
{ 
    // returns an InputStream that gets data from the named file 
    private static InputStream getFileInputStream(String fileName) 
    { 
    InputStream inputStream; 

    try { 
     inputStream = new FileInputStream(new File(fileName)); 
    } 
    catch (FileNotFoundException e) {  // no file with this name exists 
     System.err.println(e.getMessage()); 
     inputStream = null; 
    } 
    return inputStream; 
    } 

    // @SuppressWarnings("unchecked") 
    public static void main(String[] args) 
    { 


    InputStream in = System.in; 

     in = getFileInputStream(args[0]); 
     System.out.println("number of words is" + in); 


    if (in != null) 
    { 

     // Using a Scanner object to read one word at a time from the input stream. 

     @SuppressWarnings("resource") 
     Scanner sc = new Scanner(in); 
     String word; 

     System.out.println("CS261 - Assignment 1 -AdamDavis%n%n"); 
     System.out.println(""); 
     System.out.println(""); 

     // Continue getting words until we reach the end of input 
     List<String> inputWords = new ArrayList<String>(); 
     HashMap<String, List<String>> wordPairs = new HashMap<String,  List<String>>(); 

     while (sc.hasNext()) 
     { 
     word = sc.next();  
     if (!word.equals(null)) 
     { 

      inputWords.add(word); 

      System.out.println(""); 
      System.out.println(""); 
     } 
     } 

     Iterator<String> it = inputWords.iterator(); 
     boolean firstWord = true; 
     String currentWord = null; 
     String previousWord = null; 


     while(it.hasNext()) 
      { 
       currentWord = it.next(); 
       wordPairs.put(currentWord, new ArrayList<String>()); 
       if(firstWord == true) 
       { 
        //System.out.println("this is result inside if first == null:" + wordPairs.containsKey(currentWord)); 
        firstWord = false; 
        } 
       else 
       { 
       // System.out.println("this is result inside else:" + currentWord); 
        wordPairs.get(previousWord).add(currentWord); 
        //System.out.println("this is result inside else:" + wordPairs.containsKey(previousWord)); 

       } 

        previousWord = currentWord; 

        } 


      { 
       Entry<String, List<String>> Pairs = iter.next(); 
       System.out.println("this is the key in pairs: " +Pairs.getKey()); 

        Pairs.getValue(); 
        System.out.println("this is the key in pairs: " +Pairs.getValue()); 

        int count = 0; 
        if(iter.hasNext()) 
        { 

         count ++; 

      } 

     Set<Entry<String, List<String>>> s = wordPairs.entrySet(); 
     Iterator<Entry<String, List<String>>> itr=s.iterator(); 

    while(itr.hasNext()) 
    { 
     Entry<String, List<String>> Pairs = itr.next(); 
     System.out.println(Pairs.getKey()+"\t"+Pairs.getValue()); 
    } 
} 


} 

}

+0

Не можете ли вы создать свой собственный класс для хранения пар слов? –

+0

вы можете использовать 'Map >' или - если вы не собираетесь считать каждое вхождение в пару - 'Map >' –

+0

Возможно, '' HashMap > '' сделал бы это? – NikolayKondratyev

ответ

1

Вы можете использовать Apache Commons org.apache.commons.collections.map.MultiKeyMap, который позволяет хранить больше одного ключа, а затем просто добавить целое число в качестве значения для поддержания счетчика.

MultiKeyMap map = new MultiKeyMap(); 
    Integer counter = new Integer(1); 
    map.put("String1","String2",counter); 
    Integer value = (Integer)map.get("String1", "String2"); 

Или вы можете создать комбинированный ключ для такой карты. Слово1 + word2. Затем используйте целое число для продолжения

Map<String,Integer> map = new HashMap<>(); 

    String key = "word1" + "|" + "word2"; 

    Integer value = new Integer(1); 

    map.put(key,value); 
    Integer cntr = map.get(key); 
0

Я хотел бы сделать что-то вроде следующего:

  • выбрать некоторый разделитель, как #
  • сохранить каждую пару со счетчиком в карте, например, FIRST#SECOND -> 2, SECOND#THIRD -> 1

Код:

Map<String, Integer> pairsCount = new HashMap<>(); 
Iterator<String> it = inputWords.iterator(); 
String currentWord = null; 
String previousWord = null; 
while(it.hasNext()) { 
    currentWord = it.next(); 
    if(previousWord != null) { 
    String key = previousWord.concat("#").concat(currentWord); 
    if(pairsCount.containsKey(key)) { 
     Integer lastCount = pairsCount.get(key); 
     pairsCount.put(key, lastCount + 1); 
    } else { 
     pairsCount.put(key, 1); 
    } 
    } 
    previousWord = currentWord; 
} 

// output all pairs with count 
for(Map.Entry<String, Integer> entry : pairsCount.entrySet()) 
    System.out.printf("%s %s -> %d", entry.getKey().split("#")[0], entry.getKey().split("#")[1], entry.getValue()); 
0

Вы можете использовать Java 8 потоков для создания HashMap с графом пару слов в ней.

import java.util.Arrays; 
import java.util.ArrayList; 
import java.util.List; 
import java.util.Map; 
import java.nio.file.Files; 
import java.nio.file.FileSystems; 
import static java.util.stream.Collectors.groupingBy; 
import static java.util.stream.Collectors.counting; 


public class Words { 
    public static void main(String[] args) throws Exception { 
    String fileContent = new String(Files.readAllBytes(FileSystems.getDefault().getPath(args[0]))); 
    String[] inputWords = fileContent.split("\\s+"); 
    System.out.println("number of words is " + inputWords.length); 

    List<List<String>> wordPairs = new ArrayList<>(); 

    String previousWord = null; 
    for(String word: inputWords) { 
     if(previousWord != null) wordPairs.add(Arrays.asList(previousWord, word)); 
     previousWord = word; 
    } 

    Map<List<String>, Long> pairCounts = wordPairs.stream().collect(groupingBy(pair -> pair, counting())); 
    System.out.println(pairCounts); 
    } 
} 
Смежные вопросы