Как расшифровать список слов с помощью HashMap?

#java #string #methods #hashmap

#java #строка #методы #hashmap

Вопрос:

В основном мне будут предоставлены два больших входных файла. Один будет списком слов, другой будет списком тех же самых слов, но слова будут зашифрованы. Я должен использовать HashMap, чтобы получить список слов и зашифрованных слов, а затем распечатать зашифрованное слово с реальным словом рядом с ним в алфавитном порядке.

Например:

птица rdib

tca cat

gdo dog

и т.д.

Пока у меня возникли некоторые проблемы. Я создал метод для сортировки и получения ключа из слов, но я не уверен, куда идти дальше. Я думаю, мне все еще нужно поработать с зашифрованными словами, а затем распечатать все. Любая помощь, объясняющая эти вещи, была бы очень признательна, поскольку я впервые использую HashMap. Мой текущий, очень неполный код приведен ниже.

 import java.io.*;
import java.util.*;

public class Project5
{
    public static void main (String[] args) throws Exception
    {

        BufferedReader dictionaryList = new BufferedReader( new FileReader( args[0] ) );
        BufferedReader scrambleList = new BufferedReader( new FileReader( args[1] ) );

        HashMap<String, String> dWordMap = new HashMap<String, String>(); 

        while (dictionaryList.ready())
        {
            String word = dictionaryList.readLine();
            dWordMap.put(createKey(word), word);
        }
        dictionaryList.close();

        while (scrambleList.ready())
        {
            String scrambledWords = scrambleList.readLine();
            List<String> dictionaryWords = dWordMap.get(createKey(scrambledWords));
            System.out.println(scrambledWords   " "   dictionaryWords);
        }
        scrambleList.close();
    }   
    private static String createKey(String word)
    {
        char[] characterWord = word.toCharArray(); 
        Arrays.sort(characterWord);
        return new String(characterWord);
    }
  

Комментарии:

1. Сохраните слова на карте из wordWithOrderedLetters => actualWord .

2. Вы также должны изменить эту строку: BufferedReader scrambleList = new BufferedReader( new FileReader( args[0] ) ); на: BufferedReader scrambleList = new BufferedReader( new FileReader( args[1] ) ); потому что в противном случае вы просто читаете файл.

Ответ №1:

Сделайте dWordMap просто HashMap<String, String> . Для строки, в которой вы не уверены, выполните dWordMap.put(createKey(word), word) .

Затем перебираем scrableList и слово есть dWordMap.get(createKey(scrambledWord)) .

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


Ключевая концепция, которую нужно понять о HashMap, заключается в том, что она позволяет O(1) проверять, содержит ли карта данный ключ, и O(1) извлекать значение, связанное с данным ключом. Это означает, что эти операции занимают постоянное время — независимо от того, содержит ли карта 5 элементов или 5000, потребуется столько же времени, чтобы определить, содержит ли карта "ehllo" . Если вы хотите проверить эти два списка (словарь и скремблированный), вам нужен ключ, который будет одинаковым для обоих. Как вы начали делать в своем решении, сортировка букв в word — хороший выбор. Итак, ваша HashMap будет выглядеть примерно так:

 {
  "ehllo": "hello",
  "dlorw": "world"
}
  

Один проход по списку словарей создает эту карту, затем другой проход через него берет зашифрованное слово, сортирует в нем буквы, затем проверяет карту, чтобы найти расшифрованное слово.

Комментарии:

1. Map<String, String> не будет работать, потому что «собака» и «бог» могут быть зашифрованы в одну и ту же строку.

2. @talex Описание проблемы немного расплывчатое, но я думаю, оно предполагает, что список слов будет таким, что между зашифрованными и расшифрованными словами будет взаимно однозначное соотношение.

3. @talex Это не имеет значения. Если в скремблированном списке есть «ogd», невозможно узнать, возвращать ли «dog» или «god». Мы могли бы определить правило для такого случая (скажем, вернуть расшифрованное слово, которое идет первым в алфавитном порядке), но в заявленной задаче такого требования нет. Если бы мы определили такое правило, мы бы все равно использовали <String, String>

4. @talex Мое решение неявно использует правило «если два словарных слова имеют одинаковые буквы, верните ту, которая встречается последней в списке словарей». Как справиться с этим краевым случаем, было бы хорошим вопросом к тому, кто предоставил требования.

5. @Kip извините за расплывчатое описание; должен быть только один экземпляр каждого слова. Когда я перебираю список скремблирования с помощью dWordMap.get(CreateKey(scrambledWord)), я получаю сообщение об ошибке, в котором строка не может быть преобразована в List<String> . Я отредактировал свой пост, чтобы включить цикл.

Ответ №2:

Вы должны разбить эту задачу на более мелкие части. Проверьте, работает ли каждый из них, прежде чем переходить к следующему.

Сначала вам нужен метод, который превращает слово в ключ. Строка, содержащая буквы слова в алфавитном порядке, является хорошим ключом. Итак, напишите что-нибудь, что пройдет тест:

 assertEquals("dgo", createKey("dog");
assertEquals("act", createKey("cat");
  

Далее вам нужно заполнить вашу карту словами из вашего списка. Вам нужно что-то, что проходит этот тест:

 Map<String,String> map = new HashMap<>();
addToMap(map,"dog");
assertEquals("dog", map.get("dgo");
  

Ваш addToMap() метод будет использовать createKey() .

Теперь должно быть ясно, что вы можете использовать созданную вами карту и createKey() находить «dog» в любом порядке:

 Map<String,String> map = new HashMap<>();
addToMap(map,"dog");
assertEquals("dog", map.get(createKey("odg"));
  

Вы можете инкапсулировать это в метод, чтобы:

 Map<String,String> map = new HashMap<>();
addToMap(map,"dog");
assertEquals("dog", getFromScrambledWord(map,"odg"));
  

Все, что осталось, это собрать все это вместе:

  • Перебирайте свой файл словаря и вызывайте addToMap() для каждой строки
  • Перебирайте файл с зашифрованным словом, вызывайте getFromScrambledWord() для каждого из них, печатайте результат

Если вам также нужно расположить этот список в алфавитном порядке, то вместо его печати сохраните результат в a List , отсортируйте список, а затем просмотрите его для печати.


Я намеренно сделал это не очень объектно-ориентированным, потому что вы явно новичок. Чтобы сделать вещи более OO, сделайте карту закрытым полем в своем собственном классе:

 public class WordStore {
    private final Map<String,String> words = new HashMap<>();

    public void addWord(String word) {
       // your implementation here
    }

    public String getFromScrambled(String scrambledWord) {
       // your implementation here
    }
}
  

Таким образом, тест будет больше похож на:

 WordStore store = new WordStore(); // the Map is inside the WordStore
store.addWord("dog"); // like addToMap()
assertEquals("dog", store.getFromScrambled("odg"));