我想找到文本文件中引用的名称。作者可以拥有任意数量的名称和标题。只有在所有名称都匹配时才会找到匹配项(例如,名为“John Doe”的人在仅包含“John”的文本中不匹配
我现在解决它的方法是将名称拆分为标记,并将第一个标记存储在HashSet中,并将小写字符串作为键。每个令牌都包含一组名称中的下一个标记,依此类推。
这会导致很多HashSet对象增加开销。我认为有更好的方法来处理这个问题?如果可能,我更喜欢图书馆,但任何事情都会有所帮助
如果那里有好的解决方案,我愿意切换到Python。
答案 0 :(得分:0)
你能用正则表达式吗?根据文本文件的不同,您可能需要使用多行匹配,如下所示。
Pattern p = Pattern.compile("John\\s+Doe", Pattern.MULTILINE);
Matcher m = p.matcher("I am looking for John \nDoe, I am.");
System.out.println(m.find());
您也可以使用命令行实用程序pcregrep
执行此操作 - 请参阅此related question。
更新:为了解决存储名称的问题,用于存储相关字符串的内存高效结构是Trie,可能有用 - 可能有很多免费实现虽然据我所知,Java标准库中没有一个。另请参阅this question以及this one以获取一些建议。
答案 1 :(得分:0)
据我了解您的问题,您必须为每位作者存储任意名称列表,并有效地匹配它们。
我假设您已经解决了解析名称,删除非必要/可选部分(如'Dr')以及保留像'von'和'de'这样的粒子的问题。您的规范化名称必须是固定大小写的字符串序列(小写是正常的,但我坚持使用大写或标题大小写)。
现在,List<String>
或String[]
可用作包含其他详细信息的HashMap
的密钥。这样做不会很好,我担心,因为两者都是可变的,我不确定他们的hashCode()
方法是否适合这种情况。
所以我想出了类似的东西:
class AuthorName(object) {
private String[] parts;
public AuthorName(String... name_parts) {
assert name_parts.length > 0;
parts = name_parts;
}
@Override
public int hashCode() {
// hashCode() that only depends on name parts
int result = 0;
for (int i=0; i < parts.length; i+=1) result ^= part.hashCode();
return result;
}
}
Map<AuthorName, ...> authors = new HashMap<AuthorName, ...>();
authors.put(new AuthorName('John', 'Doe'), ...);
assert authors.get(new AuthorName('John', 'Doe')) != 0
这并没有解决许多可能的问题,例如'Joe Random User','Joe R User'和'J. R.用户'是同一个人。这应该在不同的层面上解决。
如果您更详细地陈述您的案例,只需一两个例子,答案可能会更好。