地图地图 - 在java的词对 - 被困住

时间:2010-01-15 03:17:21

标签: java

我正在使用MSDOS Windows提示来管道文件..它是一个带有单词的常规文件。(不像abc,def,ghi..etc)

我正在尝试编写一个程序来计算每个单词对在文本文件中出现的次数。单词对由两个连续的单词组成(即一个单词和直接跟在其后面的单词)。在本段的第一句中,“计数”和“如何”这两个词是单词对。

我希望程序做的是,接受这个输入:

abc def abc ghi abc def ghi jkl abc xyz abc abc abc ---

应该产生这个输出:

abc:
abc, 2
def, 2
ghi, 1
xyz, 1

def:
abc, 1
ghi, 1

ghi:
abc, 1
kl, 1

jkl:
abc, 1

xyz:
abc, 1

虽然我的意见不是那样的。我的意见更像是: “西雅图amazoncom预计将报告” 那么我甚至需要测试“abc”吗?

我最大的问题是将它添加到地图中...所以我想

我想我需要使用地图的地图?我不知道怎么做?

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

我认为地图会为我产生这个输出:这正是我想要的......

Key    |    Value           number of times
--------------------------
abc    |    def, ghi, jkl    3  
def    |    jkl, mno         2

如果该地图是正确的,在我的情况下我将如何从文件中添加它? 我试过了:

if(words.contain("abc"))        // would i even need to test for abc?????

{
 uniqueWords.put("abc", words, ?)  // not sure what to do about this?
}

这是我到目前为止所做的。

import java.util.Scanner;
import java.util.ArrayList;
import java.util.TreeSet;
import java.util.Iterator;
import java.util.HashSet;

public class Project1
{
public static void main(String[] args)
{
    Scanner sc = new Scanner(System.in); 
    String word;
    String grab;
    int number;

    // ArrayList<String> a = new ArrayList<String>();
    // TreeSet<String> words = new TreeSet<String>();
     Map<String, Map<String, Integer>> uniquWords = new HashMap<String, Map<String, Integer>>();

    System.out.println("project 1\n");

    while (sc.hasNext()) 
    {
        word = sc.next();
        word = word.toLowerCase();

        if (word.matches("abc"))      // would i even need to test for abc?????
        {
            uniqueWords.put("abc", word);  // syntax incorrect i still need an int!
        }

        if (word.equals("---"))
        {
            break;
        }
    }

    System.out.println("size");
    System.out.println(uniqueWords.size());

    System.out.println("unique words");
    System.out.println(uniqueWords.size());

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

我希望有人可以帮助我,因为我现在正在敲打我的脑袋并且几周没有学会任何东西..谢谢......

5 个答案:

答案 0 :(得分:1)

在你的表中,你有Key |价值|次数。对于每个第二个单词,“nubmer of times”是否具体?这可能有效。

我在上一个问题中的建议是使用列表地图。每个唯一的单词都有一个关联的List(开头为空)。在处理结束时,您将计算列表中所有相同的单词以获得总计:

Key   |  List of following words
abc   |   def def ghi mno ghi

现在,您可以在列表中计算相同的项目,以找出: abc - &gt; def = 2 abc - &gt; ghi = 2 abc - &gt; mno = 1

我认为这种方法或你的方法会很好用。我会把一些代码放在一起并更新这篇文章是没有其他人回应。

答案 1 :(得分:1)

您已将uniqueWords初始化为地图地图,而不是字符串地图,因为您正在尝试填充它。为了使您的设计正常工作,您需要将Map<String, Integer>作为“abc”键的值。

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

System.out.println("project 1\n");

while (sc.hasNext()) 
{
    word = sc.next();
    word = word.toLowerCase();

    if (word.matches("abc"))      // would i even need to test for abc?????  
                                  // no, just use the word 
    {
        uniqueWords.put("abc", word);  // <-- here you are putting a String value, instead of a Map<String, Integer>
    }

    if (word.equals("---"))
    {
        break;
    }
}

相反,你可以做类似于以下蛮力方法的事情:

    Map<String, Integer> followingWordsAndCnts = uniqueWords.get(word);
    if (followingWordsAndCnts == null) {
        followingWordsAndCnts = new HashMap<String,Integer>();
        uniqueWords.put(word, followingWordsAndCnts); 
    }
    if (sc.hasNext()) {
        word = sc.next().toLowerCase();
        Integer cnt = followingWordsAndCnts.get(word);
        followingWordsAndCnts.put(word, cnt == null? 1 : cnt + 1);
    }  

你可以将它作为递归方法,以确保每个单词轮流作为下一个单词和正在被跟随的单词。

答案 2 :(得分:1)

为每个键(例如“abc”)你要存储另一个字符串(例如“def”,“abc”)与整数(1,2)配对

我会下载google collections并使用Map&lt; String,Multiset&lt; String&gt;&gt;

Map<String, Multiset<String>> myMap = new HashMap<String, Multiset<String>>();
...

void addPair(String word1, String word2) {
    Multiset<String> set = myMap.get(word1);
    if(set==null) {
        set = HashMultiMap.create();
        myMap.put(word1,set);
    }
    set.add(word2);
}

int getOccurs(String word1, String word2) {
    if(myMap.containsKey(word1))
    return myMap.get(word1).count(word2);
    return 0;
}

如果您不想使用Multiset,您可以创建逻辑等效项(出于您的目的,而非通用目的):

多重集&LT;字符串&GT; === Map&lt; String,Integer&gt;
Map&lt; String,Multiset&lt; String&gt;&gt; === Map&lt; String,Map&lt; String,Integer&gt;&gt;

答案 3 :(得分:1)

我提出了这个解决方案。我认为你对Map的想法可能更优雅,但运行这个让我们看看我们是否可以改进:

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

public class Main {

   private static List<String> inputWords = new ArrayList<String>();
   private static Map<String, List<String>> result = new HashMap<String, List<String>>();

    public static void main(String[] args) {

        collectInput();
        process();
        generateOutput();
    }

     /*
     * Modify this method to collect the input
     * however you require it
     */
    private static void collectInput(){
        // test code
        inputWords.add("abc");
        inputWords.add("def");
        inputWords.add("abc");
        inputWords.add("ghi");
        inputWords.add("abc");
        inputWords.add("def");
        inputWords.add("abc");
    }

    private static void process(){

        // Iterate through every word in our input list
        for(int i = 0; i < inputWords.size() - 1; i++){

            // Create references to this word and next word:
            String thisWord = inputWords.get(i);
            String nextWord = inputWords.get(i+1);

            // If this word is not in the result Map yet,
            // then add it and create a new empy list for it.
            if(!result.containsKey(thisWord)){
                result.put(thisWord, new ArrayList<String>());
            }

            // Add nextWord to the list of adjacent words to thisWord:
            result.get(thisWord).add(nextWord);
        }
   }

     /*
     * Rework this method to output results as you need them:
     */
    private static void generateOutput(){
        for(Entry e : result.entrySet()){
            System.out.println("Symbol: " + e.getKey());

            // Count the number of unique instances in the list:
            Map<String, Integer>count = new HashMap<String, Integer>();
            List<String>words = (List)e.getValue();
            for(String s : words){
                if(!count.containsKey(s)){
                    count.put(s, 1);
                }
                else{
                    count.put(s, count.get(s) + 1);
                }
            }

            // Print the occurances of following symbols:
            for(Entry f : count.entrySet()){
                System.out.println("\t following symbol: " + f.getKey() + " : " + f.getValue());
            }
        }
        System.out.println();
    }
}

答案 4 :(得分:1)

按字母顺序排列答案......只需将所有HashMap放入TreeMap即可。例如:

new HashMap&gt;();' 成 新的TreeMap&gt;();

并且不要忘记添加import java.util.TreeMap;