【问题标题】:Most efficient data structure for searching for a word in text Java用于在文本 Java 中搜索单词的最有效数据结构
【发布时间】:2014-09-03 15:06:12
【问题描述】:

我有一个程序可以读取文档并在每个页面中搜索给定的搜索词。然后它会返回该单词出现在哪些页面中。

即“辉煌”一词出现在以下页面中:1,4,6,8

目前我将文件拆分为页面并将其存储到 ArrayList 中。 ArrayList 的每个元素包含文档的一页

然后我拆分页面上的每个单词并将其存储到一个 hashMap 中,其中 KEY 是该单词出现在文本中的位置(我需要知道这一点以用于其他功能),值是该单词。然后我使用 HashMap 搜索;

if (map.containsValue(searchString) == true)
                return true;
             else
                 return false;

我对每一页都这样做。

一切正常,但我想知道是否有更有效的数据结构可以使用,它可以存储给定页面上的所有单词以及它出现在页面上的位置?(因为搜索地图中的值没有给出密钥是 0(n))。

我需要能够搜索这个结构并找到一个单词。请记住,我还需要该位置以供以后使用。

我用来用文本中单词的位置填充地图的代码是;

    // text is the page of text from a document as a string
int key = 1; // position of the word in the text
    for (String element : text.split(" "))
            {
                map.put(key, element);
                key++;
            }

【问题讨论】:

    标签: java search hashmap


    【解决方案1】:

    为什么不只使用一个HashMap<String,ArrayList<Position>> 将单词映射到出现的位置?文本的每个单词都是地图中的一个键,页码和位置将形成条目列表。

    由于列表值,插入有点棘手:

    ArrayList<Position> positions = words.get(word);
    if (positions == null) {
      positions = new ArrayList<Position>();
      words.put(word, positions);
    }
    positions.add(position);
    

    或者,您可以使用 Guava Multimap:http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Multimap.html(特别是如果您已经将 Guava 用于其他目的 - 我可能会避免为此引入库依赖项)

    编辑:将整数更改为位置(并将集合更改为列表),忽略了需要确切位置。位置应该类似于

    class Position {
      int page;
      int index; 
    }
    

    【讨论】:

    • 感谢您的回复,您是说将文档存储在 hashMap 中,其中字符串是每页上的文本,而 Set 是页码?
    • 字符串将是单个单词,整数集将包含该单词出现的页码(我已尝试在答案文本中澄清这一点)
    • 但为了计算单词出现在的页码,我需要使用与在我的原始帖子中类似的算法,它需要 0(n)。我希望避免这种情况并尽可能使用更有效的方法
    • @Steve 您每次搜索文档时都会执行 O(n),而不是一次搜索文档。这是巨大的差异。
    • 这个解决方案中存储的单词的位置在哪里?
    【解决方案2】:

    我自己可能会使用LuceneGuava collections 中的其他内容,但除非我认为最有效的结构是:

    HashMap<String, TreeMap<Integer, TreeSet<Integer>>> words;
    
            ^^^^^^          ^^^^^^^          ^^^^^^^
             word            page            position
    

    使用words.get("brilliant").keySet(); 会立即为您提供所有显示“精彩”的页面。如果我没记错的话,那是 O(log n) 而不是 O(n)

    在阅读 cmets 之后,您还需要在每个搜索词之前和之后检索该词,我认为您需要第二个数据结构来进行该查找:

    TreeSet<Integer, TreeMap<Integer, String>> positions;
    
            ^^^^^^^          ^^^^^^^  ^^^^^^
             page            position  word
    

    或者,使用两个列表的相应索引作为页面和位置:

    ArrayList<ArrayList<String>> positions;          
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-03-20
      • 1970-01-01
      • 2017-09-09
      • 1970-01-01
      • 2013-06-21
      • 2011-07-02
      • 2014-03-09
      • 1970-01-01
      相关资源
      最近更新 更多