java - Java 计算单词对

标签 java collections count

我有这个编程作业,这是我们类第一次用 Java 编写代码。我已经询问了我的导师,但没有得到任何帮助。

程序需要计算文件中的单词对,并像这样显示它们:

abc:
   hec, 1

这意味着文本文件中只有一次“abc”后面跟着“hec”。我必须使用java中的集合框架。这是我到目前为止所拥有的。

 import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.FileNotFoundException;
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;

// By default, this code will get its input data from the Java standard input,
// java.lang.System.in. To allow input to come from a file instead, which can be
// useful when debugging your code, you can provide a file name as the first
// command line argument. When you do this, the input data will come from the
// named file instead. If the input file is in the project directory, you will
// not need to provide any path information.
//
// In BlueJ, specify the command line argument when you call main().
//
// In Eclipse, specify the command line argument in the project's "Run Configuration."

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;
    }

    public static void main(String[] args)
    {
    // Create an input stream for reading the data.  The default is
    // System.in (which is the keyboard).  If there is an arg provided
    // on the command line then we'll use the file instead.

    InputStream in = System.in;
    if (args.length >= 1) {
        in = getFileInputStream(args[0]);

    }

    // Now that we know where the data is coming from we'll start processing.  
    // Notice that getFileInputStream could have generated an error and left "in"
    // as null.  We should check that here and avoid trying to process the stream
    // data if there was an error.

    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.printf("CS261 - Assignment 1 - Matheus Konzen Iser%n%n");

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

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

            // do something with each word in the input
            // replace this line with your code (probably more than one line of code)

            inputWords.add(word);
        }

            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);
            }


            //OUTPUT
            for(Entry e : result.entrySet()){
                System.out.println(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("   " + f.getKey() + ", " + f.getValue());
                }
            }


        }
        System.out.printf("%nbye...%n");
    }
    }
}

我现在遇到的问题是它运行下面的循环次数太多了:

if (!word.equals("---")) {

    // do something with each word in the input
    // replace this line with your code (probably more than one line of code)

    inputWords.add(word);
}

有人对此有什么想法或建议吗?

最佳答案

我发现这部分令人困惑:

while (sc.hasNext()) {  
    word = sc.next();       
    if (!word.equals("---")) {
        // do something with each word in the input
        // replace this line with your code (probably more than one line of code)

        inputWords.add(word);
    }

    for(int i = 0; i < inputWords.size() - 1; i++){

我认为你的意思可能更像是这样的:

// Add all words (other than "---") into inputWords
while (sc.hasNext()) {  
    word = sc.next();       
    if (!word.equals("---")) {
        inputWords.add(word);
    }
}

// Now iterate over inputWords and process each word one-by-one
for (int i = 0; i < inputWords.size(); i++) {

看起来您正在尝试首先将所有单词读入 inputWords 中,然后处理它们,而您的代码会在您添加的每个单词之后迭代列表。

另请注意,for 循环中的条件过于保守,因此您会错过最后一个单词。删除 - 1 将为您提供每个单词的索引。

关于java - Java 计算单词对,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16096682/

相关文章:

r - 根据组包含的值计算组之间观察计数的差异

oracle - 根据多行的存在(序列号)从 SQL 中选择所有行

javascript - 从 postman 中的剪贴板复制数据

java - writeInt(Integer) 覆盖零

.net - 类似于 IDictionary<TKey, TValue>,但仅适用于 .NET 中的键(不需要值)?

collections - 具有非空值的 Kotlin 映射

collections - 一步销毁集合中的主干模型?

java - 使用 System.setProperty 在 Android 中设置 keystore 和信任库

java - 如何使用 spring boot 和嵌入式 tomcat 禁用 TLSv1.0?

c# - 使用 C# 解析 HTML 和计数标签