Java:在基于正则表达式的HashMap键中搜索?

2022-09-04 00:52:24

我正在使用HashMap构建一个同义词库来存储同义词。

我试图根据正则表达式搜索单词:该方法必须将字符串作为参数并返回结果数组。这是我的第一次尝试:

public ArrayList<String> searchDefinition(String regex) {
    ArrayList<String> results = new ArrayList<String>();

    Pattern p = Pattern.compile(regex);

    Set<String> keys = thesaurus.keySet();
    Iterator<String> ite = keys.iterator();

    while (ite.hasNext()) {
        String candidate = ite.next();
        Matcher m = p.matcher(candidate);
        System.out.println("Attempting to match: " + candidate + " to "  + regex);
        if (m.matches()) {
            System.out.println("it matches");
            results.add(candidate);
        }
    }   

    if (results.isEmpty()) {
        return null;
    }
    else {
        return results;
    }
}

现在,这并不像我预期的那样有效(或者也许我错误地使用了正则表达式)。如果我在哈希映射中具有以下键:

cat, car, chopper

然后通过打电话或我得到.searchDefinition("c")searchDefinition("c*")null

  1. 如何按预期进行此操作?
  2. 有没有比HashMap更好的数据结构来保持同义词库所需的类似内容?(只是好奇,至于这个任务,我们被要求使用Java集合映射)。graph
  3. 在上面的代码中,我还在不恰当地做了什么?

谢谢 丹

编辑:我已经纠正了这个例子。即使我使用正确的大小写,它也不起作用。


答案 1

您需要指定不区分大小写 Pattern.compilePattern.CASE_INSENSITIVE 。要查找包含 a 的单词,您需要使用 matcher.find()。Matcher.matches() 尝试匹配整个字符串。( "c",)c


答案 2

但是,嗯:

(a) 如果您打算始终按顺序搜索哈希地图,为什么要使用哈希地图?这是处理哈希键的大量浪费开销,并且当您从未使用它们时。当然,一个简单的ArrayList或LinkedList会是一个更好的主意。

(b) 这与同义词库有什么关系?为什么要使用正则表达式搜索同义词库?如果我想知道“猫”的同义词,我会认为我会搜索“猫”,而不是“c.*”。

关于如何构建同义词库,我的第一个想法是...好吧,我想我要问的第一个问题是,“同义词是等价关系吗?”,即如果A是B的同义词,那么B是A的同义词吗?如果A是B的同义词,B是C的同义词,那么A是C的同义词吗?假设这些问题的答案是“是”,那么我们想要构建的是将语言中的所有单词划分为同义词集的东西,这样我们就可以将每个集合中的任何单词映射到该集合中的所有其他单词。所以你需要的是一种方法来获取任何单词,将其映射到某种连接点,然后从该连接点到映射到它的所有单词。

这在数据库上很简单:只需创建一个包含两列的表,例如“word”和“token”,每个列都有自己的索引。所有同义词都映射到同一个令牌。令牌可以是任何东西,只要它对于任何给定的同义词集都是唯一的,就像序列号一样。然后搜索给定的单词,找到关联的令牌,然后获取具有该令牌的所有单词。例如,我们可以创建(big,1),(large,1),(gigantic,1),(cat,2),(cat,2)等的记录。搜索“大”,你得到1,然后搜索1,你得到“大”,“大”和“巨人”。

我不知道内置Java集合中的任何类可以做到这一点。我能想到的最简单的方法是构建两个协调的哈希表:一个将单词映射到标记,另一个将标记映射到单词数组。因此,表 1 可能有大>1、大>1、巨型>1、猫>2、猫>2 等。然后表2映射1->[大,大,巨型],2->[猫,猫]等。在第一个表中查找以将单词映射到标记,在第二个表中查找该标记以将该标记映射回单词列表。这很笨拙,因为所有数据都是冗余存储的,也许有更好的解决方案,但我没有把它从我的头顶上拿下来。(好吧,如果我们假设我们每次都要按顺序搜索整个单词列表,那将很容易,但是随着列表变大,性能会很糟糕。