Как определить, существует ли данное слово между двумя другими словами?

Для простоты предположим, что у меня есть два набора слов, отсортированных в алфавитном порядке. Один набор начинается с «aardvark» и заканчивается на «дыне», а другой начинается с «дыни» и заканчивается на «зебра». Слово «дыня» появляется в обоих наборах.

Если бы я принял входное слово, скажем, «банан», что было бы хорошим (и эффективным) способом определения того, к какому набору слов он должен принадлежать? Примечание: это не вопрос о том, существует ли уже слово «банан» в одном наборе, а вопрос о том, как определить, какое слово должно существует.

Если есть алгоритм, который кто-то знает, отлично. Если они могут предоставить некоторую версию на Java, еще лучше!

Edit: Следует также указать, в то время как мой пример имеет только 2 набора, я хочу, чтобы алгоритм работал с n наборами.

2
@GarrettHall - Нет, основываясь на алфавитном порядке.
добавлено автор Rsaesha, источник
@birryree - Да, дыня - это всегда последнее слово. Однако для простоты у меня есть только 2 набора. Я хочу знать алгоритм для n числа наборов.
добавлено автор Rsaesha, источник
В вашем примере, «melon» (или любое слово) всегда последний элемент в первом наборе? Если это так, это так же просто, как проверить, есть ли слово w до последнего элемента первого набора (в вашем случае это "melon" ). Предполагая, что вы имеете в виду отсортированный порядок. Обобщенный, вам просто нужно проверить каждый набор, чтобы узнать, доходит ли это слово до последнего элемента в наборе, а затем определить, находится ли оно до или после первого элемента. Если он не появился раньше, он принадлежит этому набору.
добавлено автор wkl, источник
должны существовать в зависимости от чего? категория?
добавлено автор Garrett Hall, источник

6 ответы

Допустим, у вас есть набор n . Построить список слов «раздела» в отсортированном порядке.

Тогда множество, которое оно принадлежит, просто:

List partitions = Arrays.asList("melon", "strawberry");
int setIndex = -(Collections.binarySearch(partitions, "banana")) - 1;

Это работает, потому что Collections.binarySearch возвращает позицию вставки (-1), если она не может найти ключ в списке. Если это может столкнуться с одним из слов раздела, вы должны сначала проверить, является ли результат отрицательным.

редактировать

I редактироватьed to remove the requirement for the "book-end" values ("aardvark" and "zebra") as they actually only complicated things.

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 :

Place the dividing words into an ArrayList (call it dividers) in alphabetical order:

ArrayList dividers = new ArrayList();
//... 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`
}

(Здесь множества нумеруются от нуля.)

2
добавлено
Хорошо, но что, если есть более двух наборов? Извините, забыли добавить это к исходному вопросу. Я просто использовал 2 набора для простоты, но моя фактическая программа будет иметь множество наборов, отсортированных по алфавиту. Так, например: aardvark - яблоко, яблоко - банан, банан - преступление, преступность - собака, ... и т. Д.
добавлено автор Rsaesha, источник
@birryree. Если он равен последнему слову в наборе, то должны быть возвращены оба этого набора и набор после (если он существует).
добавлено автор Rsaesha, источник
@Rsaesha - что происходит, когда слово равно последнему слову в наборе?
добавлено автор wkl, источник
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.

Очевидно, что вам может понадобиться адаптировать некоторые вызовы методов в зависимости от того, как вы их держите.

0
добавлено
    final int n = 99;//whatever

    final SortedSet[] 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...
    }
0
добавлено

Если вы храните списки двоичной кучи , то определение того, где вставить слово, займет O ( log n)

0
добавлено

Просто проверьте первую букву и посмотрите, между ли она (первая буква из набора 1) и (первая буква последнего элемента набора 1). Если он равен обеим первым буквам, перейдите к вторым буквам. Если он не подходит в этом наборе, перейдите к следующему набору. Это BigO (n * m), где n - количество множеств, а m - количество букв в вашем входном слове. Не так уж плохо ИМО.

0
добавлено
pro.jvm
pro.jvm
3 503 участник(ов)

Сообщество разработчиков Java Scala Kotlin Groovy Clojure Чат для нач-их: @javastart Наш сайт: projvm.com projvm.ru Наш канал: @proJVM Вакансии: @jvmjobs Конфы: @jvmconf

Java & Co
Java & Co
2 370 участник(ов)

Можно обсуждать с матом и без всё, что касается жабы, вплоть до холиваров. НЕ ИМЕЕТ ОТНОШЕНИЯ К САЙТУ JAVARUSH.RU ПРАВИЛА - https://t.me/javarush/75723 Вакансии сюда - https://telegram.me/joinchat/B7IzvUCnfo6d8t3yIxKguQ По вопросам - @thedude

learn.java
learn.java
1 888 участник(ов)

Чат для начинающих и не только Статистика: https://combot.org/chat/-1001083535868 Основной чат - @jvmchat

Java Underground
Java Underground
169 участник(ов)

https://vk.com/javatutorial

Javanese Questions
Javanese Questions
109 участник(ов)

Чат предназначен для обмена знаниями строго в формате в вопрос-ответ. Тема — Java, Kotlin и Android. Вопрос должен быть предварительно прогуглен, понятно и грамотно сформулирован, помечен хэштегами. Ответ — тем более. Куски кода размером в несколько строк можно писать прямо здесь, для больших кусков кода стоит использовать http://gist.github.com/, http://pastebin.com/, https://codeshare.io/ или любой аналогичный сервис. В некоторых случаях можно прикреплять скриншоты. Стикеры и гифки запрещены. Дополнять и уточнять вопросы и ответы — редактированием исходного сообщения. Обсуждения должны приводить к редактированию вопроса/ответа и удаляться. По хештегам можно искать существующие вопросы и овтеты: #вопрос #ответ #git #generics #java #server #awt #javafx #swing #kotlin #anko #tornadofx #ktor #android #recyclerView #performance #arch #network #permissions #storage #async