【问题标题】:Using BufferedReader to two dimensional array including a counter将 BufferedReader 用于包含计数器的二维数组
【发布时间】:2016-09-08 07:15:48
【问题描述】:

我为学校做的一些代码有问题。试图将其保持在我的逻辑范围内(并且天生就失败了)。只是想知道是否有任何技巧可以使这项工作;

public static String[][] sortWords(BufferedReader in, int n) throws IOException{
    String line = "";
    int ctr = 0;
    String[][] words = new String[n][2];

    for(int m = 0; m < n; m++) {
        words[m][1] = "1"; 
    }

    while((line=in.readLine())!=null) {
        String a[]=line.split(" ");    
        for(int i = 0; i < a.length; i++) {
            a[i] = a[i].toUpperCase();
            for(int h = ctr; h < n; h++) {
                if (words[h][0].equals(a[i])) {
                    words[h][1] = "" + (Integer.parseInt(words[h][1])+1);
                } else{
                    words[ctr][0] = a[i];
                    ctr++;
                    break;
                }
            }
        } 
        line=in.readLine();
    }
    return words;
}  

我要做的是获取一个很大的 txt 文件(70k 字)并剖析它。我想的这种方法可以做到以下几点; - 查找文件中的所有单词 - 找出每个单词出现的次数 - 将这两个值存储在二维数组中以便于访问。

如果我不在基地,我明白。 提前谢谢你。

【问题讨论】:

  • 您将使用此代码跳过一行}}} line=in.readLine();
  • 当您将计数设置为从 1 开始时,当您找到第一次出现的单词时,您会更新计数器并以 1 次出现和 count == 2 结束。您应该从 0 开始或移动循环中的初始化部分。而且,您将数组的长度设置为行数,但您可以找到的单词可能远不止于此。
  • HashMap&lt;String, Integer&gt; 中存储单词及其出现更容易。每次找到一个新单词时,将其放入HashMap 并将其值放入1,如果它已经在哈希中,则使用++ 或任何您想要的值来更新值。
  • 你应该去掉最后一个line=in.readLine();
  • 谢谢大家,我已经使用 HashMaps 方法对其进行了排序。关于马里奥所说的关于数组长度的内容,我已经运行了一个计算单词的方法,所以我有单词的总数,所以我将数组设置为那个,即使它会更短(由于 uiniques)。这也是问题所在,一旦我让 BufferedReader 通过一个方法它正在关闭并且什么都不做,也许如果我修复了它可能工作的 readLIne 部分(我知道怀疑)。

标签: java arrays bufferedreader


【解决方案1】:

所有的 cmets 都是正确的,但我会尝试将它们翻译成代码。在每个步骤中,我都注释掉了所有未修改的行,以便更改更清晰。

首先,搞定那个二维数组。使用起来既限制又麻烦。让我们改用地图:

public static Map<String, Integer> sortWords(BufferedReader in) throws IOException{
//    String line = "";
    Map<String, Integer> wordsCount = new HashMap<>();
//
//    while((line=in.readLine())!=null) {
//        String a[]=line.split(" ");
//        for(int i = 0; i < a.length; i++) {
//            a[i] = a[i].toUpperCase();
            Integer count = wordsCount.get(a[i]); // Get current count for this word
            if (count == null) count = 0; // Initialize on first appearance
            count++; // Update counter
            wordsCount.put(a[i], count); // Save the updated value
//        }
//        line=in.readLine();
//    }
//    return words;
//}

不需要初始化数组,不需要额外的循环,不需要Stringint 的转换......只需获取与该单词关联的值并更新它。而且现在我们不需要事先知道字数,所以第二个int n参数可以安全地去掉!

现在,我看到您正在使用一个非常基本的、类似 C 的、2000 年前的习语(所有这些 for(;;) 和数组等)。这是完全有效的,但你错过了更现代和更有用的结构。那么我们如何使用自 2004 年以来可用的 enhanced for loop

//public static Map<String, Integer> sortWords(BufferedReader in) throws IOException{
//    String line = "";
//    Map<String, Integer> wordsCount = new HashMap<>();
//
//    while((line=in.readLine())!=null) {
//        String a[]=line.split(" ");
        for(String word : a) {
            word = word.toUpperCase();
            Integer count = wordsCount.get(word); // Get current count for this word
//            if (count == null) count = 0; // Initialize on first appearance
//            count++; // Update counter
            wordsCount.put(word, count); // Save the updated value
//        }
//        line=in.readLine();
//    }
//    return wordsCount;
//}

更清晰的语法,我们确切地知道我们在循环中处理的是什么类型的对象......而且最重要的是,它可以让您内联一些代码以使其更清晰。像这样:

//public static Map<String, Integer> sortWords(BufferedReader in) throws IOException{
//    String line = "";
//    Map<String, Integer> wordsCount = new HashMap<>();
//
//    while((line=in.readLine())!=null) {
        for(String word : line.toUpperCase().split(" ")) {
//            Integer count = wordsCount.get(word); // Get current count for this word
//            if (count == null) count = 0; // Initialize on first appearance
//            count++; // Update counter
//            wordsCount.put(word, count); // Save the updated value
//        }
//        line=in.readLine();
//    }
//    return wordsCount;
//}

现在toUpperCase() 方法每行只调用一次,而不是每个单词一次,我们摆脱了伤害每个人眼睛的String a[] ;-P

剩下要做的最后一件事是在最后删除多余的readLine()。这样做,现在你的代码应该是这样的:

public static Map<String, Integer> sortWords(BufferedReader in) throws IOException {
    String line = "";
    Map<String, Integer> wordsCount = new HashMap<>();

    while ((line = in.readLine()) != null) {
        for(String word : line.toUpperCase().split(" ")) {
            Integer count = wordsCount.get(word); // Get current count for this word
            if (count == null) count = 0; // Initialize on first appearance
            count++; // Update counter
            wordsCount.put(word, count); // Save the updated value
        }
    }
    return wordsCount;
}

好多了!
你可以使用这样的方法:

BufferedReader in = new BufferedReader(new FileReader("myWords.txt"));
Map words = sortWords(in);
int numberOfHellos = words.get("Hello");
int numberOfGreetings = numberOfHellos + words.get("Hi") + words.get("Howdy");

【讨论】:

  • 再次感谢您。这是完整的问题大纲以及我最终得到的结果 - github.com/AussieDropBear/H274 我不想发布所有内容,因为我想了解没有得到答案,所以再次感谢您的帮助 :)
猜你喜欢
  • 1970-01-01
  • 2013-09-06
  • 1970-01-01
  • 2016-11-05
  • 2011-10-22
  • 2014-05-27
  • 2019-10-09
  • 1970-01-01
  • 2015-03-15
相关资源
最近更新 更多