【问题标题】:Getting the occurrences of words in a file and storing them with the count of their occurences获取文件中单词的出现次数并将其与出现次数一起存储
【发布时间】:2023-03-22 15:45:01
【问题描述】:

我正在尝试读取文件中每个单词的出现次数,并将其存储在带有出现次数的哈希图中。这是我的代码。

public static void main(String[] args) {


        try {
            HashMap<String, Integer> map = sortingFromAFile("file.txt");
            printMap(map);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

    public static HashMap sortingFromAFile(String fileName) throws FileNotFoundException {

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

        Integer count = 1;

        File file = new File(fileName);

        Scanner sc = null;
        try {
            sc = new Scanner(file);
            while(sc.hasNextLine()){
                String line = sc.nextLine();
                if (map.containsKey(line)){
                    map.put(line, count++);
                }
                map.put(line, count);

            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }


        return map;
    }

    public static void printMap(HashMap map){
        Iterator it = map.entrySet().iterator();
        while(it.hasNext()){
            Map.Entry pairs = (Map.Entry)it.next();
            System.out.println(pairs.getKey() + ":" + pairs.getValue()  );
        }
    }

程序只是运行以打印出文件中的文本。我在这里做错了什么。

【问题讨论】:

  • 扫描器类对每个单词进行标记,因此 nextLine( ) 表示由空格分隔的下一个字符串。
  • 不,nextLine() 将光标移到下一行。你的意思可能是next()

标签: java file-io


【解决方案1】:

我编写了这段代码,它适用于您输入的任何类型的字符串,它返回重复的单词及其长度,也许这对您有任何帮助,您可以根据您的情况轻松更改它以从文件中读取需要的话,可以使用hashmap来存储每行重复单词的出现次数,然后与最后一行匹配的单词进行比较,以此类推。

import java.util.Arrays;
import java.util.Scanner;

/** * @author ArslanAppstellation * */

public class RedundancyDetector {

/**
 * @param args
 */
public static void main(String[] args) {
    String userinput = "";
    while (true) {
        Scanner scanner = new Scanner(System.in);
        userinput = scanner.nextLine().replaceAll("\\s", "");
        if (userinput.contains("letsquit")) {
            break;
        }

        System.out.println(redudantString(userinput));
    }

}

public static String redudantString(String longStringOfCharacters) {

    // form the N Parts
    int N = longStringOfCharacters.length();
    String[] stringParts = new String[N];
    for (int i = 0; i < N; i++) {
        stringParts[i] = longStringOfCharacters.substring(i, N);
    }
    // sort them
    Arrays.sort(stringParts);

     String longest = "";
    for (int i = 0; i < N - 1; i++) {
        String iteratedLongest = matchWords(stringParts[i],
                stringParts[i + 1]);
        if (iteratedLongest.length() > longest.length())
            longest = iteratedLongest;
    }
    System.out.println(longest.length());
    return longest;
}

public static String matchWords(String ithElement, String ithplus1Element) {
    int length = Math.min(ithElement.length(), ithplus1Element.length());
    for (int i = 0; i < length; i++) {
        if (ithElement.charAt(i) != ithplus1Element.charAt(i))
            return ithElement.substring(0, i);
    }
    return ithElement.substring(0, length);
} }

【讨论】:

    【解决方案2】:

    你有一个计数错误以及Scanner类的错误使用,更改:

    while(sc.hasNextLine()){
        String line = sc.nextLine();
        if (map.containsKey(line)){
            map.put(line, count++);
        }
        map.put(line, count);
    
    }
    

    到:

    while(sc.hasNext()){
        String word = sc.next();
        if (map.containsKey(word)){
            map.put(word, map.get(word)+1);
        }
        else {
            map.put(word, 1);
        }
    }
    

    【讨论】:

    • ` 整数存在=map.get(word); if (present!=null){ present=present+1; } else { map.put(word, 1); }` 对于循环内的更新来说要快一些
    • @user1289300 这并不快:不要忘记在地图上执行的所有操作的运行时间都是 O(1) ;)
    • 除此之外不起作用,因为 Integer 是不可变的,我显然是指上面的可变 Integer 包装器,你是对的,它的 o(1) 并且尽管存在差异可以忽略不计
    • @user1289300 int 不变性与此解决方案无关。我们不是在“改变”一个整数,我们所做的是更新存储在映射中的键以具有新值。
    • 不完全是,你更新值,因为键和值在我的情况下是可变整数包装器,所以你可以更新值对象而不更新键的值,我的意思是我的第一条评论不起作用不是你的解决方案
    【解决方案3】:

    你需要分割线然后使用地图,否则你只是在读取和添加线,如果线不一样,你会得到每条线出现 1 次。

     String [] words= line.split("[\\W]");
    

    【讨论】:

    • 如果我的理解是正确的,scanner 类会标记每个单词,因此 nextLine( ) 表示下一个由空格分隔的字符串。
    • 打印线,让我知道它有什么,已经很长时间没有使用Java,但它似乎没有像你尝试的那样工作。
    • docs.oracle.com/javase/7/docs/api/java/util/Scanner.html 这里明确提到了 nextLine() 将扫描仪推进到当前行并返回被跳过的输入。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-03
    • 1970-01-01
    • 1970-01-01
    • 2011-06-20
    • 2013-01-21
    • 1970-01-01
    相关资源
    最近更新 更多