Выбор правильной структуры данных - PullRequest
1 голос
/ 01 октября 2011

Я пытаюсь научить себя Java. Я пытаюсь написать программу, которая берет строку без пробелов и разделяет ее на слова.

Мой план атаки состоял в том, чтобы разделить словарь по длине слова, а затем пройтись по строке, чтобы найти возможные варианты.

У меня возникла проблема с составлением словаря. Я читал о различных коллекциях и думал, что массив (длиной около 20), содержащий HashSets, будет работать лучше для меня, но я не могу понять, как его объявить. Я думаю, что массив был бы хорош, потому что индекс представлял бы длину, тогда HashSet был бы хорош, потому что я мог бы хранить слова в качестве ключей для быстрого поиска.

Это то, что я мог бы сделать за несколько секунд на языках сценариев, с которыми мне удобнее всего, но я потратил около 5 часов, читая и пытаясь понять это на Java. Исторически говоря, это доказательство того, что я делаю что-то в корне неправильно. Может ли кто-нибудь с большим количеством java навыков помочь мне?

Ответы [ 4 ]

2 голосов
/ 01 октября 2011

Я не понимаю, зачем вам нужен массив хэш-наборов. Вот что я предлагаю:

Set<String> dictionary = new HashSet<String>();

dictionary.add("One");
dictionary.add("Two");
dictionary.add("Three");
dictionary.add("Four");

А вот как бы я это использовал. Примечание: не читайте ниже, если только вы не хотите получить реальный ответ на проблему с ключевыми словами. Это может уменьшить, сколько обучения вы получаете. Так что читайте его, только если у вас все в порядке с испорченным.

List<String> split(String sentence) {
    List<String> words = new LinkedList<String>();
    String word = ""; // StringBuilder actually is not orders faster in 
                      // this case or I would advocate using it...
    for(int i = 0; i < sentence.length(); i++) {
        word += sentence.charAt(i); // creates a new String anyway, so StringBuilder
                                    // is far less powerful
        if(dictionary.contains(word) {
            words.add(word);
            word = "";
        }
    }
    return words;
}

Некоторые проблемы:

Давайте предположим, что ваши предложения и слова написаны строчными буквами, чтобы избежать чувствительности к регистру. Давайте также предположим, что ваш словарь содержит все распространенные английские слова.

dictionary.add("this");
dictionary.add("is");
dictionary.add("a");
dictionary.add("test");

И запустите «thisisatest», и он будет правильно разделен.

Теперь, имейте в виду, есть и другие слова.

dictionary.add("i");
dictionary.add("sat");
dictionary.add("est");

Это все действительные слова. Запуск его даст вам

"this" "i" "sat" "est"

Фактически, по этой логике, КАЖДОЕ слово, начинающееся с i или a, в конечном итоге будет пропущено. И это плохо. Специально для таких слов, как "apple" Вы получите a в качестве первого слова, затем продолжите поиск "pple" и слов, начинающихся с "pple". Это вызовет много проблем!

Даже если вы сможете обойти эту проблему, вы столкнетесь с проблемами, где слова всегда действительны.

Рассмотрим "уход за деревьями". Это «дерево» «пугать» или «деревья» «заботиться». Вы не можете провести различие - когда-либо!

Так что проблема, которую вы выбрали, это, конечно, придурок!

1 голос
/ 01 октября 2011

Если ваш единственный вопрос - это синтаксис, то для создания массива из 20 HashSets синтаксис будет:

HashSet[] mySets = new HashSet[20];
0 голосов
/ 01 октября 2011
HashSet<String>[] mySets = new HashSet[20];
0 голосов
/ 01 октября 2011

Вы, вероятно, хотите что-то вроде:

HashSet[] dictionary = new HashSet[20];
// Initialize all sets.
for (int i=0; i<dictionary.length; i++) 
{
    dictionary[i] = new HashSet<String>();
}

for (String word: words) // words is array or list with all possible words
{
    dictionary[word.length()].add(word);
}
...