Java 在二维字符数组中查找单词

Java 在二维字符数组中查找单词,java,algorithm,string,Java,Algorithm,String,什么样的方法是在这样的拼图上找到给定单词的简单方法?我正在使用Java。谢谢你的帮助 一般来说,我建议使用最简单的方法,除非你的谜题很大。我不会优化任何少于0.1秒的东西,但那只是我自己 foreach box for all directions grab the string of characters in that direction lookup a dictionary 我认为你的聪明之处在于你如何设计你的字典。在本例中,我将创建一个多级哈希

什么样的方法是在这样的拼图上找到给定单词的简单方法?我正在使用Java。谢谢你的帮助


一般来说,我建议使用最简单的方法,除非你的谜题很大。我不会优化任何少于0.1秒的东西,但那只是我自己

foreach box
    for all directions
        grab the string of characters in that direction
        lookup a dictionary

我认为你的聪明之处在于你如何设计你的字典。在本例中,我将创建一个多级哈希表,其中字符选择下一级要查看的哈希表

我会将单词列表放入Trie,然后从各个方向的所有方格中进行搜索。

最简单的方法(概念上)是简单地枚举数组中所有可能的单词,然后在词汇表中检查所有可能的单词。一张地图后面的字典,一组字符串。。。或者是从互联网上下载的一本真正的词典

作为一个例子,这里的代码是找到所有可能的单词水平。。。添加其他方向只是更多的工作:

import java.util.HashSet;
import java.util.Set;

public class WordFinder {

  public static void main(String[] args) {

    String[][] words = { { "F", "Y", "Y", "H", "N", "R", "D" }, 
                         { "R", "L", "J", "C", "I", "N", "U" },
                         ...};
    Set<String> dictionnary = new HashSet<String>();
    dictionnary.add(...);

    Set<String> wordsFound = findWords(words, dictionnary);
    ...
  }

  /**
   * Find all words in the specified array present in the dictionnary.
   * 
   */
  private static Set<String> findWords(String[][] words, Set<String> dictionnary) {
    Set<String> wordsFound = new HashSet<String>();

    // Find all possible words horizontally :
    int nbrRows = words.length;
    int nbrCol = words[0].length; // We suppose we have at least one row and all row have same lengh

    // Iterate through all rows
    for (int currentRow = 0; currentRow < nbrRows; currentRow++) {
      // Iterate through all possible starting position in the current row.
      for (int beginWordIndex = 0; beginWordIndex < nbrCol; beginWordIndex++) {
        // Iterate then through all possible ending positions in the current row, so to deal with word of any lengh.
        for (int endWordIndex = beginWordIndex; endWordIndex < nbrCol; endWordIndex++) {
          // Construct a word from the begin/end indexes :
          String currentWord = getWordInRow(words, currentRow, beginWordIndex, endWordIndex);

          // Check if the word candidate really exist, if yes, store it in the wordsFound variable.
          if (dictionnary.contains(currentWord)) {
            wordsFound.add(currentWord);
          }

          // The reverse
          String reverseWord = reverseString(currentWord);
          // Check if the reverse word really exist, if yes, store it in the wordsFound variable.
          if (dictionnary.contains(reverseWord)) {
            wordsFound.add(currentWord);
          }

        }
      }
    }

    // Don't forget vertically and in diagonals too... Same principe.

    return wordsFound;
  }

  /**
   * Return a word "candidate" in the specified row, starting at beginIndex and finishing at endIndex.
   */
  private static String getWordInRow(String[][] words, int row, int beginIndex, int endIndex) {
    String currentWord = "";
    int currentPosition = beginIndex;
    while (currentPosition <= endIndex) {
      currentWord += words[row][currentPosition];
    }
    return currentWord;
  }

  /**
   * Return the reverse of a String
   */
  private static String reverseString(String string) {
    String result = "";
    for (int i = string.length()-1; i >=0;i++) {
      result+= string.charAt(i);
    }
    return result;
  }

}
import java.util.HashSet;
导入java.util.Set;
公共类寻字器{
公共静态void main(字符串[]args){
字符串[][]单词={{{“F”、“Y”、“Y”、“H”、“N”、“R”、“D”},
{“R”、“L”、“J”、“C”、“I”、“N”、“U”},
...};
Set dictionnary=newhashset();
措辞。添加(…);
Set words found=findWords(单词,字典);
...
}
/**
*查找字典中指定数组中的所有单词。
* 
*/
私有静态集合findWords(字符串[][]个单词,集合字典){
Set wordsFound=new HashSet();
//水平查找所有可能的单词:
int=words.length;
int nbrCol=words[0].length;//我们假设至少有一行,并且所有行的长度都相同
//遍历所有行
对于(int currentRow=0;currentRow
这不是最好、最有效的解决方案。但这在概念上很简单

编辑:

反向顺序:请参见编辑的代码。只需编写一个可以反转单词的函数。因为我们已经有了正常顺序的所有可能的单词,颠倒它们就足以让单词按相反的顺序排列


对角线:我相信如果你理解了我写的代码,你一定能做到。我不会代替你做家庭作业或考试。试着用一张纸和一支笔想想你会怎么做。如果你必须用手做,你会怎么做。然后,写下你的解决方案;)

有趣的问题。我将首先通过水平、垂直和对角(在两个方向)遍历拼图来建立一个“可能的单词持有者”(可能包含给定单词之一的字符序列)列表来解决这个问题。然后,我将查看在每个获得的“可能的单词持有者”中是否存在给定的单词(或其反面)(使用Java中的contains()方法)。下面是我用Java编写的代码。我没有正确地测试它,但我想它可以工作

import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;

public class WordPuzzle {

    public Set<String> findWords(char[][] puzzle, Set<String> words) {
        Set<String> foundWords = new HashSet<String>();
        int minimumWordLength = findMinimumWordLength(words);
        Set<String> possibleWords = findPossibleWords(puzzle, minimumWordLength);
        for(String word : words) {
            for(String possibleWord : possibleWords) {
                if(possibleWord.contains(word) || possibleWord.contains(new StringBuffer(word).reverse())) {
                    foundWords.add(word);
                    break;
                }
            }
        }       
        return foundWords;
    }

    private int findMinimumWordLength(Set<String> words) {
        int minimumLength = Integer.MAX_VALUE;
        for(String word : words) {
            if(word.length() < minimumLength)
                minimumLength = word.length();
        }
        return minimumLength;
    }

    private Set<String> findPossibleWords(char[][] puzzle, int minimumWordLength) {
        Set<String> possibleWords = new LinkedHashSet<String>();
        int dimension = puzzle.length; //Assuming puzzle is square
        if(dimension >= minimumWordLength) {
            /* Every row in the puzzle is added as a possible word holder */
            for(int i = 0; i < dimension; i++) {
                if(puzzle[i].length >= minimumWordLength) {
                    possibleWords.add(new String(puzzle[i]));
                }
            }
            /* Every column in the puzzle is added as a possible word holder */
            for(int i = 0; i < dimension; i++) {
                StringBuffer temp = new StringBuffer();
                for(int j = 0; j < dimension; j++) {
                    temp = temp.append(puzzle[j][i]);
                }
                possibleWords.add(new String(temp));
            }
            /* Adding principle diagonal word holders */
            StringBuffer temp1 = new StringBuffer();
            StringBuffer temp2 = new StringBuffer();
            for(int i = 0; i < dimension; i++) {
                temp1 = temp1.append(puzzle[i][i]);
                temp2 = temp2.append(puzzle[i][dimension - i - 1]);
            }
            possibleWords.add(new String(temp1));
            possibleWords.add(new String(temp2));
            /* Adding non-principle diagonal word holders */
            for(int i = 1; i < dimension - minimumWordLength; i++) {
                temp1 = new StringBuffer();
                temp2 = new StringBuffer();
                StringBuffer temp3 = new StringBuffer();
                StringBuffer temp4 = new StringBuffer();
                for(int j = i, k = 0; j < dimension && k < dimension; j++, k++) {
                    temp1 = temp1.append(puzzle[j][k]);
                    temp2 = temp2.append(puzzle[k][j]);
                    temp3 = temp3.append(puzzle[dimension - j - 1][k]);
                    temp4 = temp4.append(puzzle[dimension - k - 1][j]);
                }
                possibleWords.add(new String(temp1));
                possibleWords.add(new String(temp2));
                possibleWords.add(new String(temp3));
                possibleWords.add(new String(temp4));
            }
        }
        return possibleWords;
    }

    public static void main(String args[]) {
        WordPuzzle program = new WordPuzzle();
        char[][] puzzle = { 
                            {'F','Y','Y','H','N','R','D'},
                            {'R','L','J','C','I','N','U'},
                            {'A','A','W','A','A','H','R'},
                            {'N','T','K','L','P','N','E'},
                            {'C','I','L','F','S','A','P'},
                            {'E','O','G','O','T','P','N'},
                            {'H','P','O','L','A','N','D'}
                          };
        Set<String> words = new HashSet<String>();
        words.add("FRANCE");
        words.add("POLAND");
        words.add("INDIA");
        words.add("JAPAN");
        words.add("USA");
        words.add("HOLLAND");
        Set<String> wordsFound = program.findWords(puzzle, words);
        for(String word : wordsFound) {
            System.out.println(word);
        }
    }
}
import java.util.HashSet;
导入java.util.LinkedHashSet;
导入java.util.Set;
公共类字谜{
公共集合findWords(字符[][]拼图,集合字){
Set foundWords=new HashSet();
int minimumWordLength=findmimimumwordlength(单词);
Set-possibleWords=findPossibleWords(拼图,最小字长);
for(字符串字:字){
for(字符串possibleWords:possibleWords){
if(possibleWord.contains(word)| | possibleWord.contains(new-StringBuffer(word.reverse())){
foundWords.add(word);
打破
}
}
}       
返回单词;
}
私有int findMinimumWordLength(设置字){
int minimumLength=Integer.MAX_值;
for(字符串字:字){
if(word.length()=最小字长){
/*拼图中的每一行都被添加为可能的单词持有者*/
对于(int i=0;i=最小字长){
添加(新字符串(拼图[i]);
}
}
/*每一列