为简单起见,我们假设我有两组单词,按字母顺序排序。一组从“aardvark”开始,以“甜瓜”结束,另一组从“甜瓜”开始,以“斑马”结束。 “甜瓜”这个词出现在两组中。
如果我要输入一个输入词,说“香蕉”,那么确定它应该属于哪一组词的好方法(和有效方法)是什么?注意:这不是关于“香蕉”这个词是否已经存在于一个集合中的问题,而是一个关于如何确定单词应该存在于哪个集合的问题。
如果有人知道算法,那很好。如果他们可以用Java提供一些版本,那就更好了!
编辑:还应该指出,虽然我的例子只有2套,我希望算法能够使用n套。
答案 0 :(得分:2)
两套:
如果word
是你的话(例如"banana"
):
int cmp = word.compareTo("melon");
if (cmp < 0) {
// it belongs to the first set
} else if (cmp > 0) {
// it belongs to the second set
} else {
// the word is "melon"
}
适用于n
套:
按字母顺序将分隔词放入ArrayList<String>
(称之为dividers
):
ArrayList<String> dividers = new ArrayList<String>();
//... populate `dividers` ...
Collections.sort(dividers);
现在您可以使用Collections.binarySearch()
来确定该词属于哪个集合:
int pos = Collections.binarySearch(dividers, word);
if (pos >= 0) {
// the word is the divider between sets `pos` and `pos+1`
} else {
int num = -(pos + 1);
// the word belong to set number `num`
}
(这里,集合从零开始编号。)
答案 1 :(得分:2)
假设你有n
套。按排序顺序构造“分区”单词列表。
然后它所属的集合就是:
List<String> partitions = Arrays.asList("melon", "strawberry");
int setIndex = -(Collections.binarySearch(partitions, "banana")) - 1;
这是有效的,因为Collections.binarySearch
如果找不到列表中的键,则返回插入位置(-1)。如果它可能与其中一个分区单词发生碰撞,那么您应首先检查结果是否为负数。
我编辑了删除“书籍结束”值(“aardvark”和“zebra”)的要求,因为它们实际上只是复杂化了。
答案 2 :(得分:0)
只需检查第一个字母,看看它是否在(第1组的第一个字母)和(第1组的最后一个元素的第一个字母)之间。如果它等于两个首字母,则移到第二个字母。如果它不适合该组移动到下一组。这是BigO(n * m),其中n是集合的数量,m是输入单词中的字母数。 IMO也不错。
答案 3 :(得分:0)
String mid = firstList.get(firstList.size()-1);
assert(mid.equals(secondList.get(0)));
if(newString.compareTo(mid) < 0) // belongs in first
else // belongs in second.
显然,您可能需要调整一些方法调用,具体取决于您持有它们的方式。
答案 4 :(得分:0)
如果您使用binary heap来存储列表,那么确定插入单词的位置将需要O(log n)
答案 5 :(得分:0)
final int n = 99; // whatever
final SortedSet<String>[] allMySets = new SortedSet[ n ];
// put your sets into allMySets, no particular order required.
final String searchWord = "banana";
int i;
for ( i = 0; i < allMySets.length; i++ ) {
final SortedSet< String > ss = allMySets[i];
if ( searchWord.compareTo( ss.first() ) >= 0 && searchWord.compareTo( ss.last() ) <= 0 ) {
System.out.println("Word " + searchWord + " belongs to set #" + i);
break;
}
}
if ( i == allMySets.length ) {
System.out.println("No matching set found.");
// Maybe handle border case here...
}