Nano Hash - криптовалюты, майнинг, программирование

Обработка двумерного текста (решатель Ruzzle)

Я пытаюсь запрограммировать Java-приложение Ruzzle Solver для целей обучения. У меня есть небольшая проблема с «нахождением слов» на карте типа Ruzzle.

Пример карты Ruzzle (она состоит из 4 строк и 4 столбцов по 1 букве в каждой ячейке):

Z O O H
E Y L H
I E L I
H O F M

http://www.maclife.com/files/imagecache/futureus_imagegallery_fullsize/gallery/ruzzle1.jpg

Я хотел бы получить список всех возможных слов, которые вы можете найти на такой карте.

Сложность: вы можете найти слово, добавляя буквы по вертикали, горизонтали и диагонали (пример: «ПРИВЕТ»).

На данный момент я создал 3 класса:

  • Ruzzlesolver.java

  • Письмо.java

  • Map.java

Класс письма

Описывает одну букву карты, ее поля — это позиции X и Y, а также символ ячейки.

Класс Ruzzlesolver

Это основной класс.

  • он читает карту Ruzzle (построчный ввод в консоли)
  • он читает файл dictionnary.txt
  • он сравнивает карту с файлом словаря
  • он записывает в файл results.txt

Каждая строка хранится в массиве символов. Затем я создаю новый объект Map из 4 полученных массивов.

Класс карты

Это конструктор объектов Map:

public Map(final char[] pTab1, final char[] pTab2, final char[] pTab3, final char[] pTab4)
{
    this.aLettres = new ArrayList<Letter>();
    for (int i = 0 ; i < 4 ; i++) {
        this.aLettres.add(new Letter(1, i+1, pTab1[i]));}
    for (int i = 0 ; i < 4 ; i++) {
        this.aLettres.add(new Letter(2, i+1, pTab2[i]));}
    for (int i = 0 ; i < 4 ; i++) {
        this.aLettres.add(new Letter(3, i+1, pTab3[i]));}
    for (int i = 0 ; i < 4 ; i++) {
        this.aLettres.add(new Letter(4, i+1, pTab4[i]));}
}

this.aLettres — это список ArrayList, содержащий каждую из 16 букв карты.

Каждая буква знает свой столбец (позиция X: "i+1"), свою строку (позиция Y: "1, 2, 3 и 4") и свой символ ("pTab[i]").

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

Метод содержит()

Это моя проблема: я застрял, используя следующий метод:

Как это называется

  1. Я выбираю слово из словаря в классе Ruzzlesolver.
  2. Я вызываю метод contains() для моего объекта Map с этим словом в качестве параметра:

    if (this.aMap.contains(vMot)) {/*print vMot in the result.txt file*/}
    

Как работает метод contains()

  1. Переменные:

        char[] vChars = new char[pMot.length()];
        ArrayList<Letter> vFoundCharS1 = new ArrayList<Letter>();
    
  2. Хранение каждого символа pMot в ArrayList:

        for (int i = 0 ; i < pMot.length() ; i++) {
            vChars[i] = pMot.charAt(i);
        }
    
  3. Поиск первого символа pMot:

        for (Letter vL : this.aLettres) {
            if (vL.getChar() == vChars[0]) {
                vFoundCharS1.add(vL);
                return true;
            }
        }
    
  4. Я застрял.


Если я продолжу этот метод, мне придется создавать все более и более длинные блоки по мере продвижения. Кроме того, мне нужно было бы написать 16 блоков, чтобы учесть все возможные длины.

Я уверен, что это неправильный метод. Как бы вы реализовали такое лечение?

Заранее большое спасибо за вашу помощь.

PS: Прошу прощения за грамматические/английские ошибки, английский не мой родной язык.

22.05.2013

  • Вы хотите, чтобы это было эффективно или приемлема грубая сила? 22.05.2013

Ответы:


1

Если я правильно понял задачу, вы можете выбрать каждую соседнюю ячейку для следующей буквы, верно? В этом случае приведенный ниже код (я думаю) решит вашу проблему.

Я изменил конструктор Map, потому что с двумерным массивом char проще работать.

Функция contains делает именно то, что описано в шаге 3: найдите первую букву и попробуйте выполнить поиск оттуда. Функция findRecursively ищет оставшуюся часть слова рекурсивно.

public class Map {
    private char[][] board;

    public Map(final char[] pTab1, final char[] pTab2, 
           final char[] pTab3, final char[] pTab4) {
        board = new char[4][4];

        for (int i = 0 ; i < 4 ; i++) {
            board[0][i] = pTab1(i);
            board[1][i] = pTab2(i);
            board[2][i] = pTab3(i);
            board[3][i] = pTab4(i);
        }
    }

    public boolean contains(String word) {
        char[] array = word.toCharArray();

        // empty string is trivial
        if (array.length == 0)
            return true;

        for(int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                if (board[i][j] == array[0] && findRecursively(i, j, array, 1))
                    return true;
            }
        }

        return false;
    }

    public boolean isValid(int i, int j) {
        return (0 <= i && i < 4) && (0 <= j && j < 4);
    }

    public boolean findRecursively(int i, int j, char[] array, int index) {
        // reached end of word
        if (index == array.length) {
            return true;
        } else {
            // loop over all neighbors
            for (int di = -1; di <= 1; di++) {
                for (int dj = -1; dj <= 1; dj++) {
                    // skip cell itself and invalid cells
                    if (!(di == 0 && dj == 0) && isValid(i+di, j+dj)) {
                        if (board[i+di][j+dj] == array[index] 
                              && findRecursively(i+di, j+dj, array, index+1))
                            return true;
                    }
                }
            }

            return false;
        }           
    }
}
22.05.2013
  • Ваша реализация выглядит очень хорошо, я попробую завтра. Спасибо за вашу помощь, я скажу вам, если это работает для меня. 23.05.2013
  • Только будьте осторожны, потому что этот код не запрещает возвращаться к одной и той же букве несколько раз. Вы должны быть уверены, что игра позволяет это. 23.05.2013
  • @AndréNeves Вы правы, мне нужно было найти способ предотвратить двойное чтение одной и той же ячейки в одном и том же слове, используя двумерный массив логических значений. Я закончил свою программу благодаря вам двоим. 26.05.2013
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

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

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..