Java 处理二维文本(Ruzzle解算器)

Java 处理二维文本(Ruzzle解算器),java,text,map,matrix,Java,Text,Map,Matrix,我正试图为学习目的编写一个Ruzzle solver Java应用程序。 在Ruzzle类型的地图中“查找单词”这件事上我有一个小问题 Ruzzle贴图示例(由4行4列组成,每个单元格中有1个字母): 我想获得一份你能在这样一张地图上找到的所有可能单词的列表 难点:你可以通过垂直、水平和对角添加字母来找到一个单词(例如:“HELLO”) 到目前为止,我创建了3个类: Ruzzlesolver.java Letter.java java 字母类 描述贴图的单个字母,其字段为X和Y位置以及单元

我正试图为学习目的编写一个Ruzzle solver Java应用程序。 在Ruzzle类型的地图中“查找单词”这件事上我有一个小问题

Ruzzle贴图示例(由4行4列组成,每个单元格中有1个字母):

我想获得一份你能在这样一张地图上找到的所有可能单词的列表

难点:你可以通过垂直、水平和对角添加字母来找到一个单词(例如:“HELLO”)

到目前为止,我创建了3个类:

  • Ruzzlesolver.java

  • Letter.java

  • java

字母类 描述贴图的单个字母,其字段为X和Y位置以及单元格的字符

Ruzzlesolver类 这是主课

  • 它读取Ruzzle映射(控制台中的逐行输入)
  • 它读取dictionnary.txt文件
  • 它将地图与字典文件进行比较
  • 它会写入results.txt文件
每行存储在一个字符数组中。 然后,我从获得的4个数组中创建一个新的Map对象

地图类 这是映射对象的构造函数:

public Map(final char[] pTab1, final char[] pTab2, final char[] pTab3, final char[] pTab4)
{
    this.aLettres = new ArrayList<Letter>();
    for (int i = 0 ; i < 4 ; i++) {
        this.aLettres.add(new Letter(1, i+1, pTab1[i]));}
    for (int i = 0 ; i < 4 ; i++) {
        this.aLettres.add(new Letter(2, i+1, pTab2[i]));}
    for (int i = 0 ; i < 4 ; i++) {
        this.aLettres.add(new Letter(3, i+1, pTab3[i]));}
    for (int i = 0 ; i < 4 ; i++) {
        this.aLettres.add(new Letter(4, i+1, pTab4[i]));}
}
contains()方法是如何工作的
  • 变量:

        char[] vChars = new char[pMot.length()];
        ArrayList<Letter> vFoundCharS1 = new ArrayList<Letter>();
    
  • 我被卡住了

  • 如果我继续使用这种方法,我将不得不在前进的过程中创建越来越长的块。此外,我需要写16个块来考虑每一个长度的可能性。< /P> 我确信这是一种错误的方法。您将如何实施这种治疗

    非常感谢你的帮助


    PS:我为语法/英语错误道歉,英语不是我的母语。

    如果我理解正确,你可以为下一个字母选择每个相邻的单元格,对吗?在这种情况下,下面的代码(我认为)可以解决您的问题

    我更改了
    Map
    的构造函数,因为使用
    char
    的二维数组更容易

    函数
    包含的
    正是步骤3所描述的功能:找到第一个字母,然后尝试从那里继续搜索。函数
    findRecursive
    递归搜索单词的其余部分

    public class Map {
        private char[][] board;
    
        public Map(final char[] pTab1, final char[] pTab2, 
               final char[] pTab3, final char[] pTab4) {
            board = new char[4][4];
    
            for (int i = 0 ; i < 4 ; i++) {
                board[0][i] = pTab1(i);
                board[1][i] = pTab2(i);
                board[2][i] = pTab3(i);
                board[3][i] = pTab4(i);
            }
        }
    
        public boolean contains(String word) {
            char[] array = word.toCharArray();
    
            // empty string is trivial
            if (array.length == 0)
                return true;
    
            for(int i = 0; i < 4; i++) {
                for (int j = 0; j < 4; j++) {
                    if (board[i][j] == array[0] && findRecursively(i, j, array, 1))
                        return true;
                }
            }
    
            return false;
        }
    
        public boolean isValid(int i, int j) {
            return (0 <= i && i < 4) && (0 <= j && j < 4);
        }
    
        public boolean findRecursively(int i, int j, char[] array, int index) {
            // reached end of word
            if (index == array.length) {
                return true;
            } else {
                // loop over all neighbors
                for (int di = -1; di <= 1; di++) {
                    for (int dj = -1; dj <= 1; dj++) {
                        // skip cell itself and invalid cells
                        if (!(di == 0 && dj == 0) && isValid(i+di, j+dj)) {
                            if (board[i+di][j+dj] == array[index] 
                                  && findRecursively(i+di, j+dj, array, index+1))
                                return true;
                        }
                    }
                }
    
                return false;
            }           
        }
    }
    
    公共类映射{
    私人char[][]董事会;
    公共地图(最终字符[]pTab1,最终字符[]pTab2,
    最终字符[]pTab3,最终字符[]pTab4){
    board=新字符[4][4];
    对于(int i=0;i<4;i++){
    董事会[0][i]=pTab1(i);
    董事会[1][i]=pTab2(i);
    董事会[2][i]=pTab3(i);
    董事会[3][i]=pTab4(i);
    }
    }
    公共布尔包含(字符串字){
    char[]数组=word.toCharArray();
    //空字符串是微不足道的
    如果(array.length==0)
    返回true;
    对于(int i=0;i<4;i++){
    对于(int j=0;j<4;j++){
    if(board[i][j]==数组[0]&&find(i,j,数组,1))
    返回true;
    }
    }
    返回false;
    }
    公共布尔值有效(int i,int j){
    
    return(0如果我正确理解了问题,您可以为下一个字母选择每个相邻的单元格,对吗?在这种情况下,下面的代码(我认为)可以解决您的问题

    我更改了
    Map
    的构造函数,因为使用
    char
    的二维数组更容易

    函数
    包含的
    与步骤3中描述的一样:查找第一个字母,然后尝试从那里继续搜索。函数
    以递归方式查找单词的其余部分

    public class Map {
        private char[][] board;
    
        public Map(final char[] pTab1, final char[] pTab2, 
               final char[] pTab3, final char[] pTab4) {
            board = new char[4][4];
    
            for (int i = 0 ; i < 4 ; i++) {
                board[0][i] = pTab1(i);
                board[1][i] = pTab2(i);
                board[2][i] = pTab3(i);
                board[3][i] = pTab4(i);
            }
        }
    
        public boolean contains(String word) {
            char[] array = word.toCharArray();
    
            // empty string is trivial
            if (array.length == 0)
                return true;
    
            for(int i = 0; i < 4; i++) {
                for (int j = 0; j < 4; j++) {
                    if (board[i][j] == array[0] && findRecursively(i, j, array, 1))
                        return true;
                }
            }
    
            return false;
        }
    
        public boolean isValid(int i, int j) {
            return (0 <= i && i < 4) && (0 <= j && j < 4);
        }
    
        public boolean findRecursively(int i, int j, char[] array, int index) {
            // reached end of word
            if (index == array.length) {
                return true;
            } else {
                // loop over all neighbors
                for (int di = -1; di <= 1; di++) {
                    for (int dj = -1; dj <= 1; dj++) {
                        // skip cell itself and invalid cells
                        if (!(di == 0 && dj == 0) && isValid(i+di, j+dj)) {
                            if (board[i+di][j+dj] == array[index] 
                                  && findRecursively(i+di, j+dj, array, index+1))
                                return true;
                        }
                    }
                }
    
                return false;
            }           
        }
    }
    
    公共类映射{
    私人char[][]董事会;
    公共地图(最终字符[]pTab1,最终字符[]pTab2,
    最终字符[]pTab3,最终字符[]pTab4){
    board=新字符[4][4];
    对于(int i=0;i<4;i++){
    董事会[0][i]=pTab1(i);
    董事会[1][i]=pTab2(i);
    董事会[2][i]=pTab3(i);
    董事会[3][i]=pTab4(i);
    }
    }
    公共布尔包含(字符串字){
    char[]数组=word.toCharArray();
    //空字符串是微不足道的
    如果(array.length==0)
    返回true;
    对于(int i=0;i<4;i++){
    对于(int j=0;j<4;j++){
    if(board[i][j]==数组[0]&&find(i,j,数组,1))
    返回true;
    }
    }
    返回false;
    }
    公共布尔值有效(int i,int j){
    
    返回(0)您希望这是高效的还是暴力可以接受?您希望这是高效的还是暴力可以接受?您的实现看起来很好,我明天会尝试一下。感谢您的帮助,我会告诉您它是否对我有效。请小心,因为此代码不禁止多次返回同一个字母。哟你必须确保游戏允许这样做。@AndréNeves你是对的,我必须找到一种方法,防止同一个单元格在同一个单词中被读取两次,使用一个二维布尔数组。多亏了你们两个,我完成了我的程序。你的实现看起来很好,我明天会尝试一下。谢谢你的帮助,我会告诉你它是否适合你我。只是要小心,因为这个代码并不禁止多次返回同一个字母。你必须确保游戏允许这样做。@AndréNeves你是对的,我必须找到一种方法,防止同一个单元格在同一个单词中被读取两次,使用一个二维布尔数组。多亏了你们两个,我完成了我的程序。
        for (int i = 0 ; i < pMot.length() ; i++) {
            vChars[i] = pMot.charAt(i);
        }
    
        for (Letter vL : this.aLettres) {
            if (vL.getChar() == vChars[0]) {
                vFoundCharS1.add(vL);
                return true;
            }
        }
    
    public class Map {
        private char[][] board;
    
        public Map(final char[] pTab1, final char[] pTab2, 
               final char[] pTab3, final char[] pTab4) {
            board = new char[4][4];
    
            for (int i = 0 ; i < 4 ; i++) {
                board[0][i] = pTab1(i);
                board[1][i] = pTab2(i);
                board[2][i] = pTab3(i);
                board[3][i] = pTab4(i);
            }
        }
    
        public boolean contains(String word) {
            char[] array = word.toCharArray();
    
            // empty string is trivial
            if (array.length == 0)
                return true;
    
            for(int i = 0; i < 4; i++) {
                for (int j = 0; j < 4; j++) {
                    if (board[i][j] == array[0] && findRecursively(i, j, array, 1))
                        return true;
                }
            }
    
            return false;
        }
    
        public boolean isValid(int i, int j) {
            return (0 <= i && i < 4) && (0 <= j && j < 4);
        }
    
        public boolean findRecursively(int i, int j, char[] array, int index) {
            // reached end of word
            if (index == array.length) {
                return true;
            } else {
                // loop over all neighbors
                for (int di = -1; di <= 1; di++) {
                    for (int dj = -1; dj <= 1; dj++) {
                        // skip cell itself and invalid cells
                        if (!(di == 0 && dj == 0) && isValid(i+di, j+dj)) {
                            if (board[i+di][j+dj] == array[index] 
                                  && findRecursively(i+di, j+dj, array, index+1))
                                return true;
                        }
                    }
                }
    
                return false;
            }           
        }
    }