简体   繁体   中英

Java - Searching through a 2D array of characters for words?

So I've been creating a program that plays boggle when the user enters a word, it runs a search for the first letter through a 2D array of characters (the boggle board) and if it finds it, it searches all the characters around it. But it only does this once and prints the letters around the first letter of the inputted word. How can I go about adding a function or adding onto my current functions that allows it to keep searching for letters through the inputted word until the full word is found, or is not found? Would I have to keep calling over the checkSurrounding() function?

 private static void checkForFirstLetter(char[][] boggle, String word) {
    for(int i = 0; i < 5; i++) {
        for(int j = 0; j < 5; j++) {
            if(boggle[i][j] == word.charAt(0)) {
                System.out.println("\nFound " + boggle[i][j] + " at (" + (j+1) + ", " + (i+1) + ")!");
                checkSurrounding(boggle, j, i);
            }
        }
    }
}


private static void checkSurrounding(char[][] boggle, int x, int y) {
    for(int dx = -1; dx <= 1; dx++) {
        if ((x + dx >= 0) && (x + dx < boggle.length)) {
            for(int dy = -1; dy <= 1; dy++) {
                if ((y + dy >= 0) && (y + dy < boggle[x + dx].length) && (!(dx == 0 && dy == 0))) {
                    System.out.print(boggle[y + dy][x + dx]);
                }
            }
        }
    } 
}

Yes, I would do a recursion for checkSurrounding once you found a character that begins the start of the word. In that function, I would include a parameter for the word itself. When checking for a character that comes next in the word, if I find a character that is at index 0 of word, then I recurse, but only looking at the last n-1 characters of word, ignoring the character you just found. If you were to use this implementation, you would need to keep track of which characters you've already come across, so that you ignore characters that have already been found.

You were actually very close to having everything you need to match the whole word. The key is to use recursion to try to extend a partial match into the 8-neighbours of the currently matching character.

One thing you have to be careful of is to not consider letters on the board more than once in a match. The trick is to clear the current letter by setting it to blank before checking neighbors - this ensures that it can't be part of any future match. Once you've considered all the neighbors you set the letter back to its original value.

The code below just counts how many different matches were found. It would be really nice to keep track of the letter positions of each match, but that's a little trickier.

This is mostly your code, with a few additions:

static int checkForFirstLetter(char[][] board, String word)
{
  int count = 0;
  for (int x = 0; x < board.length; x++) {
    for (int y = 0; y < board.length; y++) {
      if (board[x][y] == word.charAt(0)) {
        count += checkSurrounding(board, x, y, word, 0);
      }
    }
  }
  return count;
}

static int checkSurrounding(char[][] board, int x, int y, String word, int i)
{
  if (i == word.length()) 
    return 1;

  if (board[x][y] != word.charAt(i)) 
    return 0;

  int count = 0;

  // Clear the current position so we don't consider it again in a match
  board[x][y] = 0;
  for (int dx = -1; dx <= 1; dx++) {
    if ((x + dx >= 0) && (x + dx < board.length)) {
      for (int dy = -1; dy <= 1; dy++) {
        if ((y + dy >= 0) && (y + dy < board[x + dx].length) && (!(dx == 0 && dy == 0))) {
          count += checkSurrounding(board, x + dx, y + dy, word, i + 1);
        }
      }
    }
  }
  // Reinstate the character at the current position, which has to be at pos i in word
  board[x][y] = word.charAt(i);

  return count;
}

Test:

public static void main(String[] args)
{
  char[][] board = {
      {'o', 'x', 'o', 'x', 'o'},
      {'x', 'o', 'x', 'o', 'x'},
      {'o', 'x', 'o', 'x', 'o'},
      {'x', 'o', 'x', 'o', 'x'},
      {'o', 'x', 'o', 'x', 'o'}};

  for(char[] b : board)
    System.out.println(new String(b).replaceAll(".", "$0 "));

  int count = checkForFirstLetter(board, "oxo");
  System.out.printf("\nFound %d word(s)\n", count);
}

Output:

o x o x o 
x o x o x 
o x o x o 
x o x o x 
o x o x o 

Found 604 word(s)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM