如何确定给定的单词是否介于两个单词之间?

时间:2011-10-27 19:02:06

标签: java

为简单起见,我们假设我有两组单词,按字母顺序排序。一组从“aardvark”开始,以“甜瓜”结束,另一组从“甜瓜”开始,以“斑马”结束。 “甜瓜”这个词出现在两组中。

如果我要输入一个输入词,说“香蕉”,那么确定它应该属于哪一组词的好方法(和有效方法)是什么?注意:这不是关于“香蕉”这个词是否已经存在于一个集合中的问题,而是一个关于如何确定单词应该存在于哪个集合的问题。

如果有人知道算法,那很好。如果他们可以用Java提供一些版本,那就更好了!

编辑:还应该指出,虽然我的例子只有2套,我希望算法能够使用n套。

6 个答案:

答案 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...
    }