【问题标题】:Recursive array search of char arraychar数组的递归数组搜索
【发布时间】:2016-10-11 18:03:13
【问题描述】:

我试图弄清楚如何递归地搜索一个 char 数组中的一个单词并返回它是否存在。把它想象成相当于单词搜索的编程。我当前的代码如下。种子值 9999 有助于测试。如何编写递归搜索方法来验证任何给定单词在 char 数组中是否存在?

public class Board {

   private char[][] board = new char[4][4];
   private boolean[][] visited = new boolean[4][4];
   private String word;

   public Board(int seed){
       word = "";
       Random rand = new Random(seed);

       for(int i = 0; i < board.length; i++){
           for(int j = 0; j < board[0].length; j++){
               char randomChar = (char) (rand.nextInt(27) + 65);
               //System.out.print(" " + randomChar + " ");
               board[i][j] = randomChar;
               //System.out.print(board[i][j]);
           }//System.out.println();
       }      
   }

   public void resetBoard(){
       for(int i = 0; i < board.length; i++){
           for(int j = 0; j < board[0].length; j++){
               visited[i][j] = false;
           }
       }
   }

   public void printBoard(){
       for(int i = 0; i < board.length; i++){
           for(int j = 0; j < board[0].length; j++){
               if(j == 0)
                   System.out.println("+---+ +---+ +---+ +---+");
               System.out.print("| " + board[i][j] + " | ");
           }
           System.out.println("\n+---+ +---+ +---+ +---+");
       }
   }

   public boolean verifyWord(String w){
       this.word = w;
       for(int i = 0; i < w.length(); i++){
//           char letter = w.charAt(i);
//           System.out.println(letter);
           boolean wordVerify = verifyWordRecursively(0, 0, 0);
           if(wordVerify == true)
               return true;
//           if(i == w.length() - 1){
//               if(wordVerify == true)
//                   return true;
//           }
       }return false;
   }

   public boolean verifyWordRecursively(int wordIndex, int row, int col){
       char letter = word.charAt(wordIndex);
       System.out.println(letter);
       if(board[row][col] == letter){
           return true;
       }
       else{
           if(col + 1 < board[0].length){
               verifyWordRecursively(wordIndex, row, col + 1);
           }
           if(row + 1 < board.length){
               verifyWordRecursively(wordIndex, row + 1, col);
           }
       }return false;
   }
}

这是我的主要课程:

public class LA2Main {

   public static void main(String[] args) throws IOException{
       int seed = getSeed();
       Board b = new Board(seed);
       b.printBoard();

       Scanner inFile = new Scanner(new FileReader("input.txt"));
//       while(inFile.hasNextLine()){
//           System.out.println(inFile.nextLine());
           String word = inFile.nextLine();
           b.resetBoard();
           System.out.println("-----------------------\n" + word);
           boolean isVerified = b.verifyWord(word);
           if(isVerified == true)
               System.out.println("'" + word + "' was found on the board!");
           else
               System.out.println("'" + word + "' is NOT on this board");
           b.printBoard();
//       }
   }

   public static int getSeed(){
       Scanner sc = new Scanner(System.in);
       int userInput;
       while(true){                                                          
           try{
               System.out.println("Enter an integer seed value greater than 0: ");
               userInput = Integer.parseInt(sc.next());
               if( userInput > 0)
                   return userInput;
           }
           catch(NumberFormatException e){
               System.out.println("Invalid!");
           }
       }
   }
}

【问题讨论】:

  • 我可能会用迭代而不是递归来做到这一点。我这样说是因为似乎有很多极端情况,并且您必须传递给递归函数的信息量会变得难以处理。 IE。首先,您只想检查您所在的字母是否是单词中的第一个字母,然后检查它周围是否有下一个字母,然后您需要朝同一个方向前进,前两个字母让您进入。这当然是可能的,但迭代似乎是我书中的方式。

标签: java arrays recursion multidimensional-array


【解决方案1】:

在字符数组中查找单词的最简单方法可能是先将其转换为String,然后使用contains,因为接下来无需重新发明轮子:

boolean contains = new String(myCharArray).contains(myWord);

这是最基本的方法,即case sensitive,如果这个词只是一个更大的词的子部分,将返回true,所以更合适将matches 与不区分大小写的正则表达式一起使用,该正则表达式定义单词边界如下:

boolean contains = new String(myCharArray).matches(
    String.format("(?i)^.*\\b%s\\b.*$", Pattern.quote(myWord))
);

【讨论】:

    【解决方案2】:

    所以我猜这个问题是关于递归字符串匹配的,尽管前面已经指出这可能不是最好的方法,但仍然可以使用。

    查看您的代码,您不想匹配 char 数组,而是匹配 char 矩阵。让我们采取幼稚的方法,因为无论如何我们都在一条低效的道路上。

    我会给出一些伪代码,让我们从一些代码开始,检查矩阵是否在某个偏移量处与数组匹配:

    function matches(char matrix[][], char needle[], int row, int col)
        width, height = dimensions(matrix)
    
        /* Check whether we're out of range */
        if (width * height < row * width + col + length(needle)) {
            return false
        }
    
        for (int i = 0 ... len(needle)) {
            if (matrix[row][col] != needle[i]) {
                return false
            }
    
            /* increment position, (hint: integer division) */
            row += (col + 1) / width
            col  = (col + 1) % width
        }
    
        return true
    

    现在这仍然不是一个递归解决方案,并且该函数有很多参数(对于代码清晰度来说不是很好)。我们先写一个包装器:

    function matches(char matrix[][], char needle[])
        recursiveMatches(matrix, needle, 0, 0)
    

    recursiveMatches 必须跟踪它的原始行和列, 进行适当的递归调用。当然,它需要一个递归调用,它之前会失败:

    function recursiveMatches(char matrix[][], char needle[], int row, int col)
        width, height = dimensions(matrix)
        originalRow, originalCol = row, col
    
        /* Check whether we're out of range */
        if (width * height < row * width + col + length(needle)) {
            return false
        }
    
        for (int i = 0 ... len(needle)) {
            if (matrix[row][col] != needle[i]) {
                /* add one to the position */
                originalRow += (originalCol + 1) / width
                originalCol  = (originalCol + 1) % width 
                return recursiveMatches(matrix, needle, originalRow, originalCol)
            }
    
            /* increment position */
            row += (col + 1) / width
            col  = (col + 1) % width
        }
    
        return true
    

    我希望将其转换为正确的 java 代码应该不会太难。

    【讨论】:

      猜你喜欢
      • 2015-04-12
      • 2013-05-12
      • 2012-09-16
      • 1970-01-01
      • 2011-04-27
      • 2018-09-20
      • 2014-10-15
      • 2014-01-07
      相关资源
      最近更新 更多