Word Solver - Все направления - PullRequest
0 голосов
/ 01 мая 2011

Я создал решатель слов для всех направлений.Он находит слова по горизонтали, вертикали и наоборот.Тем не менее, у меня есть проблемы, заставляя его идти по всем направлениям.Итак, чтобы взять «привет» в:

H  E  i  l
x  L  p  q
c  L  O  m

Кто-нибудь может подсказать мне, как это сделать?Вот мой алгоритм поиска слов (в C ++):

/*
 * For loops that search each row, each column in all 8 possible directions.
 */
void Scramble::solve() {

cout << "Output:" << endl;

for (int row = 0; row < getRows(); row++) {
    for (int col = 0; col < getCols(); col++)
        for (int rowDir = -1; rowDir <= 1; rowDir++)
            for (int colDir = -1; colDir <=1; colDir++)
                if (rowDir != 0 || colDir != 0)
                    findWords(row, col, rowDir, colDir);
}
}

/*
 * Finds the matches in a given direction. Also calls verifyWord() to verify that the
 * current sequence of letters could possibly form a word. If not, search stops.
 */
void Scramble::findWords(int startingRow, int startingCol, int rowDir, int colDir) {

int searchResult;
string sequence = "";
sequence = sequence + wordsArr[startingRow][startingCol];

for (int i = startingRow + rowDir, j = startingCol + colDir; i >= 0 && j >= 0
&& i < getRows() && j < getCols(); i = i + rowDir, j = j + colDir) {

    sequence = sequence + wordsArr[i][j];

    if (sequence.length() >= 3) {

        searchResult = verifyWord(words, sequence);

        if ((unsigned int)searchResult == words.size())
            break;

        if (words[searchResult].rfind(sequence) > words[searchResult].length())
            break;

        if (words[searchResult] == (sequence))
            cout << sequence << endl;
    }
}
}

/*
 * Performs the verifyWord search method.
 * Searches the word to make sure that so far, there is possibly that the current sequence
 * of letter could form a word. That is to avoid continuing to search for a word
 * when the first sequence of characters do not construct a valid word in the dictionary.
 *
 * For example, if we have 'xzt', when this search is done it prevents the search
 * to continue since no word in the dictionary starts with 'xzt'
 */
int Scramble::verifyWord(vector<string> words, string str) {

int low = 0;
int mid = 0;
int high = words.size();

while (low < high) {

    mid = (low + high) / 2;

    if (str > words[mid]) {
        low = mid + 1;
    }

    else if (str < words[mid]) {
        high = mid - 1;
    }

    else
        return mid;
}
}

Ответы [ 4 ]

2 голосов
/ 01 мая 2011

Вот интересный способ думать об этом: найти слово сродни решению лабиринта.«Начало» и «конец» соответствуют началу и концу слова, которое вы ищете, «тупик» соответствует несоответствию пути и вашего слова, а «успех» - это когда строка на вашем путиявляется совпадением.

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

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

0 голосов
/ 01 октября 2015

Это простая программа для написания слов, которую я написал --->

#include<iostream>

using namespace std;

int main()
{
    int a, b, i, j, l, t, n, f, g, k;
    cout<<"Enter the number of rows and columns: "<<endl;               
    cin>>a>>b;                                                              //Inputs the number of rows and columns
    char mat[100][100], s[100];
    cout<<"Enter the matrix: "<<endl;
    for (i = 0; i < a; i++) for (j = 0; j < b; j++) cin>>mat[i][j];         //Inputs the matrix
    cout<<"Enter the number of words: "<<endl;
    cin>>t;                                                                 //Inputs the number of words to be found
    while (t--)
    {
        cout<<"Enter the length of the word: "<<endl;
        cin>>n;                                                             //Inputs the length of the word
        cout<<"Enter the word: "<<endl;
        for (i = 0; i < n; i++) cin>>s[i];                                  //Inputs the word to be found
        for (i = 0; i < a; i++)                                         //Loop to transverse along i'th row
        {
            for (j = 0; j < b; j++)                                     //Loop to transverse along j'th column
            {
                f = i;
                g = j;
                for (k = 0; s[k] == mat[f][g] && k < n; k++, g++);          //Loop to find the word if it is horizontally right
                if (k == n)
                {
                    cout<<"The coordinates and direction are ---> "<<j+1<<","<<i+1<<" right"<<endl;
                    goto A;
                }
                f = i;
                g = j;
                for (k = 0; s[k] == mat[f][g] && k < n; k++, g--);      //Loop to find the word if it is horizontally left
                if (k == n)
                {
                    cout<<"The coordinates and direction are ---> "<<j+1<<","<<i+1<<" left"<<endl;
                    goto A;
                }
                f = i;
                g = j;
                for (k = 0; s[k] == mat[f][g] && k < n; k++, f++);      //Loop to find the word if it is vertically down
                if (k == n)
                {
                    cout<<"The coordinates and direction are ---> "<<j+1<<","<<i+1<<" down"<<endl;
                    goto A;
                }
                f = i;
                g = j;
                for (k = 0; s[k] == mat[f][g] && k < n; k++, f--);      //Loop to find the word if it is vertically up
                if (k == n)
                {
                    cout<<"The coordinates and direction are ---> "<<j+1<<","<<i+1<<" up"<<endl;
                    goto A;
                }
                f = i;
                g = j;
                for (k = 0; s[k] == mat[f][g] && k < n; k++, f++, g++); //Loop to find the word if it is down right
                if (k == n)
                {
                    cout<<"The coordinates and direction are ---> "<<j+1<<","<<i+1<<" down right"<<endl;
                    goto A;
                }
                f = i;
                g = j;
                for (k = 0; s[k] == mat[f][g] && k < n; k++, f--, g--); //Loop to find the word if it is up left
                if (k == n)
                {
                    cout<<"The coordinates and direction are ---> "<<j+1<<","<<i+1<<" up left"<<endl;
                    goto A;
                }
                f = i;
                g = j;
                for (k = 0; s[k] == mat[f][g] && k < n; k++, f++, g--); //Loop to find the word if it is down left
                if (k == n)
                {
                    cout<<"The coordinates and direction are ---> "<<j+1<<","<<i+1<<" down left"<<endl;
                    goto A;
                }
                f = i;
                g = j;
                for (k = 0; s[k] == mat[f][g] && k < n; k++, f--, g++); //Loop to find the word if it is up right
                if (k == n)
                {
                    cout<<"The coordinates and direction are ---> "<<j+1<<","<<i+1<<" up right"<<endl;
                    goto A;
                }
            }
        }
        A:;                                                             //If the word has been found the program should reach this point to start the search for the next word
    }
    return 0;
}

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

0 голосов
/ 01 мая 2011

1) В настоящее время ваша функция solve() ищет слово по прямой линии , начиная с каждой точки: это то, что вы намереваетесь?Я спрашиваю только потому, что «привет» не отображается в виде матрицы в виде прямой линии:

H  E  i  l
x  L  p  q
c  L  O  m

Если вы хотите, чтобы прямолинейный только слова, то хорошо (этокак я всегда понимал эти головоломки для работы в любом случае), но если на самом деле вы хотите найти слова в стиле змеиный , то рекурсивный поиск, такой как Zilchonum и BlueRajaпредложение было бы хорошей ставкой.Только будьте осторожны, вы не зацикливаетесь на уже использованных вами письмах.

2) В любом случае ваша функция verifyWord() также имеет некоторые проблемы: по крайней мере, она должна возвращать некоторыезначение в случае, когда вы выходите из цикла while (low < high).

Несмотря на это, он все равно не будет делать то, что вы хотите: например, скажем, ваш словарь содержит {"ant", "bat" "hello", "yak", "zoo"}, и вы вызываете verifyWord() с str="hel", вы хотели бы вернуть значение 2, но в данный момент он делает это:

step  low   mid  high
 0     0     0     5   // initialise
 1     0     2     5   // set mid = (0+5)/2 = 2... words[2] == "hello" 
 2     0     2     1   // "hel" < "hello" so set high = mid - 1
 3     0     0     1   // set mid = (0+1)/2 = 0... words[0] == "ant"
 4     1     0     1   // "hel" > "ant" so set low = mid + 1     
 5  // now (low<high) is false, so we exit the loop with mid==0

Вместо того, чтобы сравнивать «hel» с «hello», возможно, вы былучше обрезать слова в словаре до длины, равной str: т.е. сравнивать str с word[mid].substr(0,str.length())?

0 голосов
/ 01 мая 2011

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

...