我想比较一个提供的字符串是否以数组中的任何字符串开头。最简单的解决方案是:
String b = ...;
boolean matched = false;
for (String a : array) {
if (b.startsWith(a))
match = true;
}
然而,直观地说,我想使用像trie这样的东西来提高效率,因为字符串数组可能会变得非常大,我需要快速运行这些匹配。我可以保证这些字符串都是按字母顺序排列的。我还可以保证数组中的所有字符串都是2或更小。在Java中实现这种类似trie的结构的最佳方法是什么?我找不到任何基于Java的库。
谢谢!
答案 0 :(得分:5)
如果你真的有足够的开始字符串,它会成为一个瓶颈,一个特里可能确实有帮助。
此问题已在此网站上提出并回答:Where do I find a standard Trie based map implementation in Java?
这就是答案:https://forums.oracle.com/forums/thread.jspa?messageID=8787521
答案 1 :(得分:2)
我想比较一个提供的字符串是否以任何字符串开头 在数组中。
嗯 - 您当然可以改进目前的解决方案:
static boolean startsAny(final String b) {
for (String a : array) {
if (b.startsWith(a)) {
return true;
}
}
return false
}
您可以将String#matches与正则表达式一起使用,但我不确定这是否更有效。您是否对代码进行了分析并将其确定为瓶颈?
答案 2 :(得分:2)
一个简单的解决方案是将字符串插入Set<String>
,然后对其执行两次查找,一次使用第一个字符b
,然后如果不匹配b
的前两个字符1}}。
例如,
class StartsWithAny {
private Set<String> set;
public StartsWithAny(String[] array) {
set = new HashSet<String>();
for (String a : array) {
set.add(a);
}
}
// returns true if b starts with any strings contained in array
// with the condition that b.length() <= 2
public boolean startsWithAny(final String b) {
if (b.length() > 0 && set.contains(b.substring(0, 1))) {
return true;
}
if (b.length() > 1 && set.contains(b.substring(0, 2))) {
return true;
}
return false;
}
}
对此的一个变体是使用两个单独的Set
,一个用于单个字符查找,一个用于两个字符查找,这将稍微提高性能。
另一种类似的方法是实现二进制搜索算法,该算法将对已排序的数组进行操作并执行类似的功能。