【问题标题】:Searching for a word in multiple file : Process the files with hashmap JAVA在多个文件中搜索单词:使用 hashmap JAVA 处理文件
【发布时间】:2016-01-29 21:22:31
【问题描述】:

我正在尝试处理文件列表以将单词存储为:

 // <word,<filename, <count, position[]>>> something like this

 private static void processFile(List<File> list) throws IOException {

   int fcount = 0;
    for (File file : list) {
      String fileName = file.getName();
      // System.out.println(fileName);
      FileInputStream fstream = new FileInputStream(file);
      BufferedReader in = new BufferedReader(new InputStreamReader(fstream));
      String readLine = "";
      int pos = 0;
      while ((readLine = in.readLine()) != null) {
        ArrayList<HashMap<String, HashMap<Integer, ArrayList<Integer>>>> fList;
        String[] words = readLine.split("\\W");

        for (String newWord : words) {

          String word = newWord.toLowerCase();
          ArrayList<Integer> position = null;
          HashMap<Integer, ArrayList<Integer>> value = null;
          HashMap<String, HashMap<Integer, ArrayList<Integer>>> fnameWithCount = null;

          if (fmap.containsKey(word)) {
            fList = fmap.get(word);

            if(fList.contains(fileName)) {
              fnameWithCount =   getMap(fList,fileName);
            }

            int newCount =1;
            if (fnameWithCount != null) {
              value  = fnameWithCount.get(fileName);
              for (int prevcount : value.keySet()) {
                newCount = prevcount +1;
                value.put(newCount,value.remove(prevcount));              
              }
              value.get(newCount).add(pos);
            }  else {
              position = new ArrayList<Integer>(); // position array
              position.add(pos);

              value = new HashMap<Integer, ArrayList<Integer>>();
              value.put(1, position);

              fnameWithCount = new HashMap<String, HashMap<Integer, ArrayList<Integer>>>();
              fnameWithCount.put(fileName, value);

              fList.add(fnameWithCount);
              fmap.put(word, fList);
            }


          } else {
            position = new ArrayList<Integer>(); // position array
            position.add(pos);

            value = new HashMap<Integer, ArrayList<Integer>>();
            value.put(1, position);

            fnameWithCount = new HashMap<String, HashMap<Integer, ArrayList<Integer>>>();
            fnameWithCount.put(fileName, value);

            fList = new ArrayList<HashMap<String, HashMap<Integer, ArrayList<Integer>>>>();          
            fList.add(fnameWithCount);

            fmap.put(word, fList);

          }

          pos++;
        }
      }
      fcount++;
    }

  }

  private static HashMap<String, HashMap<Integer, ArrayList<Integer>>> getMap(
      ArrayList<HashMap<String, HashMap<Integer, ArrayList<Integer>>>> fList,
      String fileName) {


    for (int i =0 ;i <fList.size();i++) {
     if( fList.get(i).containsKey(fileName)) {
        return fList.get(i);

      }
    }

    return null;
  }

  private static HashMap<String, Integer> hashMapSearch(
      String stringToLookFor) throws IOException {


    if (fmap.containsKey(stringToLookFor.toLowerCase())) {
     System.out.println(fmap.get(stringToLookFor.toLowerCase()).toString());
    }

        return null;

  }

我的输出看起来像:

{File1={1=[0]}}, {File1={1=[37]}}, {File1={1=[72]}}, {File1={1=[93]}}, {File1={1=[106]}}, {File1={1=[111]}}, {File1={1=[120]}}, {File1={1=[123]}}, {File1={1=[132]}}, {File1={1=[143]}}, {File1={1=[170]}}, {File1={1=[178]}}, {File1={1=[187]}}, {File1={1=[191]}}, {File1={1=[203]}}, {File1={1=[212]}}, {File1={1=[219]}}, {File1={1=[228]}}, {File1={1=[232]}}, {File1={1=[249]}}, {File1={1=[253]}}, {File1={1=[260]}}, {File1={1=[272]}}, {File1={1=[279]}}, {File1={1=[284]}}, {File1={1=[305]}}, {File1={1=[333]}}, {File1={1=[337]}}, {File1={1=[340]}}, {File1={1=[351]}}, {File1={1=[367]}}, {File1={1=[377]}}, {File1={1=[391]}}, {File1={1=[403]}}, {File1={1=[420]}}, {File1={1=[427]}}, {File1={1=[437]}}, {File1={1=[445]}}, {File1={1=[474]}}, {File1={1=[479]}}, {File1={1=[485]}}, {File1={1=[495]}}, {File1={1=[519]}}, {File1={1=[522]}}, {File1={1=[526]}}, {File1={1=[529]}}, {File1={1=[555]}}, {File1={1=[571]}}, {File1={1=[582]}}, {File1={1=[604]}}, {File1={1=[607]}}, {File1={1=[611]}}, {File1={1=[618]}}, {File1={1=[623]}}, {File1={1=[628]}}, {File1={1=[640]}}, {File1={1=[644]}}, {File1={1=[663]}}, {File1={1=[683]}}, {File1={1=[689]}}, {File1={1=[699]}}, {File1={1=[708]}}, {File1={1=[715]}}, {File1={1=[725]}}, {File2={1=[0]}}, {File2={1=[5]}}, {File2={1=[100]}}, {File2={1=[140]}}, {File2={1=[145]}}, {File2={1=[153]}}, {File2={1=[171]}}, {File2={1=[184]}}, {File2={1=[207]}}, {File2={1=[210]}}, {File2={1=[214]}}, {File2={1=[219]}}, {File2={1=[223]}}, {File2={1=[234]}}, {File2={1=[244]}}, {File2={1=[247]}}, {File2={1=[259]}}, {File2={1=[264]}}, {File2={1=[270]}}, {File2={1=[273]}}, {File2={1=[278]}}, {File2={1=[326]}}, {File2={1=[331]}}, {File2={1=[340]}}, {File2={1=[355]}}, {File2={1=[367]}}, {File2={1=[371]}}, {File2={1=[375]}}, {File2={1=[378]}}, {File3={1=[47]}}, {File3={1=[68]}}, {File3={1=[73]}}, {File3={1=[102]}}, {File3={1=[121]}}, {File3={1=[161]}}]

但它应该是:

 [{File1={64=[array of positions]}}, {File2={29=[array of positions]}},  {File3={6=[array of positions]}}]

有人能告诉我这里有什么问题吗?像这样使用地图进行存储也很好吗:// &lt;word,&lt;filename, &lt;count, position[]&gt;&gt;&gt; something like this 或者我可以这样使用吗:

class SearchWord {
        String word;
        HashMap<String, Integer> fileNameWithCount; // <fileName, count>
         HashMap<String, List<Integer>> positionList;  //<fileName, pos[]>
        }

有人可以建议我的代码哪个好或有什么问题吗?

【问题讨论】:

  • 如果您有职位列表,则不需要计数,因为获取列表的大小是微不足道的。但是您必须随后格式化输出。否则,通常地图是糟糕的数据结构,因为它们不显示任何语义,但你似乎正在做一个分配,所以它可能没问题。
  • @MiserableVariable 我试图找出存储索引以使搜索更容易的最佳方式。
  • “应该是”输出是针对单个单词的,对吗? class Matches { String fileName; List&lt;Integer&gt; positions}; class Word { String word; List&lt;Matches&gt; matches; }; List&lt;Word&gt;; 似乎是最合适的,加上正确的toString(),因此您不必在打印时进行格式化。

标签: java string file search hashmap


【解决方案1】:

如果你改变 'if' 条件,它会起作用:

for (int i = 0; i < fList.size(); i++) {
  if (fList.get(i).containsKey(fileName)) {
     fnameWithCount =   getMap(fList,fileName);
  }
}

之前,您尝试在 ArrayList&lt;HashMap&lt;String, HashMap&lt;Integer, ArrayList&lt;Integer&gt;&gt;&gt;&gt;(); 上使用“包含”方法 查看文件名是否已经在列表中。但那张支票的评估结果是 每次都是假的。

【讨论】:

  • 但只有第一个文件已更改为预期。有什么方法可以根据地图的键在 ArrayList 中获取地图?不使用 for 循环?它可以通过 fList 大小循环正常工作
  • @Sarah,我的错,我已经编辑了我的答案。是的,您可以根据文件名的键获取地图。我认为不使用循环是不可能的,因为您必须检查文件名是否存在于列表中的任何位置,因此我们需要一个循环
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-01
相关资源
最近更新 更多