Sto scrivendo un puzzle di ricerca di parole in C# e mi piacerebbe essere in grado di cercare la matrice bidimensionale di caratteri per le parole in modo elegante.Come si cerca una matrice bidimensionale in qualsiasi direzione
Le ricerche di base da sinistra a destra, dall'alto in basso ecc. Non sono difficili da scrivere, tuttavia le cose iniziano a diventare un po 'prolisse durante la ricerca in diagonale sull'array. Ho funzionato, ma sono sicuro che c'è una soluzione migliore là fuori.
Ecco un esempio di un puzzle che sto cercando di risolvere, qualsiasi idea sarebbe molto apprezzata.
BXXD
AXEX
TRXX
FXXX
BAT FRED
EDIT: Complimenti a Steve per avermi dato l'idea di cercare punti cardinali
EDIT: Il risultato della ricerca deve restituire le coordinate x1, y1 e x2, y2 delle parole all'interno dell'ar ray.
MODIFICA: Grazie ad Antti per aver fornito un buon algoritmo per la ricerca dell'array.
Questo il risultato finale che ho trovato. L'ho basato sull'algoritmo nella risposta di Antti, dopo averlo modificato per restituire gli offset dell'array per l'inizio e la fine di qualsiasi parola trovata. Questo algoritmo verrà utilizzato per il gioco di ricerca di parole che sto scrivendo in WPF, per i miei figli. Grazie a tutti per avermi aiutato. Inserirò un link qui per l'app quando è rispettabile.
public class Range
{
public Range(Coordinate start, Coordinate end)
{
Start = start;
End = end;
}
public Coordinate Start { get; set; }
public Coordinate End { get; set; }
}
public class Coordinate
{
public Coordinate(int x, int y)
{
X = x;
Y = y;
}
public int X { get; set; }
public int Y { get; set; }
}
public class WordSearcher
{
public WordSearcher(char[,] puzzle)
{
Puzzle = puzzle;
}
public char[,] Puzzle { get; set; }
// represents the array offsets for each
// character surrounding the current one
private Coordinate[] directions =
{
new Coordinate(-1, 0), // West
new Coordinate(-1,-1), // North West
new Coordinate(0, -1), // North
new Coordinate(1, -1), // North East
new Coordinate(1, 0), // East
new Coordinate(1, 1), // South East
new Coordinate(0, 1), // South
new Coordinate(-1, 1) // South West
};
public Range Search(string word)
{
// scan the puzzle line by line
for (int y = 0; y < Puzzle.GetLength(0); y++)
{
for (int x = 0; x < Puzzle.GetLength(1); x++)
{
if (Puzzle[y, x] == word[0])
{
// and when we find a character that matches
// the start of the word, scan in each direction
// around it looking for the rest of the word
var start = new Coordinate(x, y);
var end = SearchEachDirection(word, x, y);
if (end != null)
{
return new Range(start, end);
}
}
}
}
return null;
}
private Coordinate SearchEachDirection(string word, int x, int y)
{
char[] chars = word.ToCharArray();
for (int direction = 0; direction < 8; direction++)
{
var reference = SearchDirection(chars, x, y, direction);
if (reference != null)
{
return reference;
}
}
return null;
}
private Coordinate SearchDirection(char[] chars, int x, int y, int direction)
{
// have we ve moved passed the boundary of the puzzle
if (x < 0 || y < 0 || x >= Puzzle.GetLength(1) || y >= Puzzle.GetLength(0))
return null;
if (Puzzle[y, x] != chars[0])
return null;
// when we reach the last character in the word
// the values of x,y represent location in the
// puzzle where the word stops
if (chars.Length == 1)
return new Coordinate(x, y);
// test the next character in the current direction
char[] copy = new char[chars.Length - 1];
Array.Copy(chars, 1, copy, 0, chars.Length - 1);
return SearchDirection(copy, x + directions[direction].X, y + directions[direction].Y, direction);
}
}
Se mostrare il vostro metodo corrente qualcuno potrebbe avere un metodo migliore. Finché non sappiamo come lo stai facendo attualmente, non possiamo davvero migliorarlo. – gingerbreadboy
È lungo e brutto e non merita davvero il tempo di criticare. Speravo che qualcuno avesse una migliore conoscenza di strutture e algoritmi di dati di quanto io possa essere in grado di indicarmi la giusta direzione. –