首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >~>解析Sudoku网格

~>解析Sudoku网格
EN

Code Review用户
提问于 2013-12-15 19:37:58
回答 1查看 1.4K关注 0票数 8

这是我第一次,非常非常-非常第一次尝试java。我还没有开始解决数独难题的实际解决方案(甚至不知道从哪里开始,还没有查看其他周末挑战条目)。我在这里没有什么可说的,但我确信它已经充满了初学者错误,所以在我让事情变得更糟之前,我想得到一个关于我所拥有的东西的回顾。

正在解析的谜题是赢得周末挑战的建议中提供的一个示例。

代码语言:javascript
复制
public class SudokuGame {

    private final static String newLine = System.lineSeparator();
    private final static String puzzle = 
            "...84...9" + newLine +
            "..1.....5" + newLine +
            "8...2146." + newLine +
            "7.8....9." + newLine +
            "........." + newLine +
            ".5....3.1" + newLine +
            ".2491...7" + newLine +
            "9.....5.." + newLine +
            "3...84...";

    public static void main(String[] args){
        SudokuGrid grid = new SudokuGrid(puzzle);
        System.out.print(grid);
    }
}

程序接受字符串并输出如下:

.=‘5’>- +===========+===========+===========+

下面是SudokuGrid类:

代码语言:javascript
复制
/** A 9x9 Sudoku grid */
public class SudokuGrid {

    private SudokuDigit[][] digits;

    /** Creates a new SudokuGrid. Specified array must be 9x9. */
    public SudokuGrid(SudokuDigit[][] digits){
        this.digits = digits;
    }

    /** Creates a new SudokuGrid from specified string, assumed to be 9 lines of 9 characters. */
    public SudokuGrid(String contents) {
        this(contents.split("\\r?\\n"));
    }

    /** Creates a new SudokuGrid from specified string array, assumed to be 9 strings of 9 characters. */
    public SudokuGrid(String[] contents) {
        this(parseStringContent(contents));
    }

    private static SudokuDigit[][] parseStringContent(String[] contents) {
        SudokuDigit[][] result = new SudokuDigit[9][9];
        for (int i = 0; i < 9; i++) {
            String row = contents[i];
            for (int j = 0; j < 9; j++) {
                result[i][j] = new SudokuDigit(row.charAt(j));
            }
        }
        return result;
    }

    /** Sets the value of specified grid coordinates. */
    public void setDigit(Point coordinates, Integer value) {
        setDigit(coordinates, new SudokuDigit(value));
    }

    /** Sets the value of specified grid coordinates. */
    public void setDigit(Point coordinates, SudokuDigit value) {
        this.digits[coordinates.x][coordinates.y] = value;
    }

    /** Gets the SudokuDigit at specified grid coordinates. */
    public SudokuDigit getDigit(Point coordinates) {
        return this.digits[coordinates.x][coordinates.y];
    }

    /** Gets all SudokuDigits in specified row (0-8). */
    public SudokuDigit[] getRow(int row) {
        return this.digits[row];
    }

    /** Gets all SudokuDigits in specified column (0-8). */
    public SudokuDigit[] getColumn(int column) {
        SudokuDigit[] result = new SudokuDigit[9];
        for (int row = 0; row < 9; row++) {
            result[row] = this.digits[row][column];
        }
        return result;
    }

    /** Gets all SudokuDigits in specified 3x3 region (x: 0-2, y: 0-2). */
    public SudokuDigit[][] getRegion(Point coordinates) {
        SudokuDigit[][] result = new SudokuDigit[3][3];
        int startRow = coordinates.x * 3;
        int startCol = coordinates.y * 3;
        for (int row = 0; row < 3; row++) {
            for (int col = 0; col < 3; col++) {
                result[row][col] = this.digits[startRow + row][startCol + col];
            }
        }
        return result;
    }

    public String toString() {
        final String newLine = System.lineSeparator();
        String result = "+===========+===========+===========+" + newLine;
        for (int row = 0; row < this.digits.length; row++) {
            result = result.concat("|");
            for (int col = 0; col < this.digits[row].length; col++) {
                result = result.concat(" " + this.digits[row][col].toString() + " |");
            }

            if ((row + 1) % 3 == 0) {
                result = result.concat(newLine + "+===========+===========+===========+" + newLine);
            }
            else {
                result = result.concat(newLine + "-------------------------------------" + newLine);
            }
        }

        return result;
    }
}

这是我的SudokuDigit课程:

代码语言:javascript
复制
/** An object that represents a single digit in a SudokuGrid, with or without a value. */
public class SudokuDigit {

    private Integer digit;

    /** Creates a new, empty value */
    public SudokuDigit() {
        this((Integer)null);
    }

    /** Creates a new digit from specified character. */
    public SudokuDigit(char value) {
        Integer numericValue;
        if (value == '.') {
            numericValue = null;
        }
        else {
            numericValue = Integer.parseInt(String.valueOf(value));
        }
        this.digit = numericValue;
    }

    /** Creates a new digit with specified value */
    public SudokuDigit(Integer value) {
        this.digit = value;
    }

    /** Gets the current value of the digit. Null if no value is specified. */
    public Integer getDigit() {
        return this.digit;
    }

    /** Sets the current value of the digit.
     *  Specify null for no value. 
     *  Throws UnsupportedOperationException if value is not valid.*/ 
    public void setDigit(Integer value) {
        if (!validateDigitValue(value)) throw new UnsupportedOperationException();
        this.digit = value;
    }

    private boolean validateDigitValue(Integer value) {
        return value == null || (value >= 1 && value <= 9); 
    }

    public String toString() {
        return this.digit != null ? this.digit.toString() : " ";
    }
}

这真是一个“你好世界!”但是我希望这段代码可以作为一个实际的Sudoku解析器的基础(如果我能把它放在一起的话,稍后我会发布它)。有什么明目张胆的错误会把我逼上砖墙吗?

EN

回答 1

Code Review用户

回答已采纳

发布于 2013-12-15 19:53:07

  • 与您的String puzzle不同,您可以使用如下所示的String[] (并不是说您必须这样做,但您应该知道存在其他选项)。您目前正在将其转换为String数组,所以为什么不从一开始就将其作为字符串数组呢?私有最终静态String[]谜=新String[]{ "...84...9“、"..1.....5”、. };
  • 这可以用private SudokuDigit[][] digits;标记,以防止任何恶意程序员在初始化后甚至尝试使用this.digits = null,或者初始化一个新的二维数组。
  • 3是一个神奇的数字。是的,这是个神奇的数字。在过去,现在和未来,我说三,是一个神奇的数字。
  • 9也是幻数。这意味着您应该使用它作为常量:公共静态最终int MAGIC_NUMBER = 9;
  • 带有变量ij的双循环可以被称为xy,以避免任何可能的混淆。
  • UnsupportedOperationException可能不是提交setDigit方法的最佳例外。IllegalArgumentException会更好,因为方法的参数是不正确的。
  • 在您的SudokuDigit char构造函数中可以简化: numericValue === '.‘?null :Integer.parseInt(String.valueOf(值));
  • 在编写JavaDoc时,我相信在多行上使用它是惯例。或者至少这比只使用一行更常见(而且,您是否知道可以在Eclipse中的方法之前编写/**,然后按enter键使Eclipse为您编写基本的“布局”?) /** *根据指定的字符创建一个新的数字。*/公共SudokuDigit(字符值){
  • 您可以在Javadoc中使用@throws来指定可以抛出的异常以及抛出原因。/** *设置数字的当前值。*不指定null值。*@如果值无效,则抛出UnsupportedOperationException。*/公开无效setDigit(整数值){
  • 您可以使用Character.digit(char c, int radix)而不是Integer.parseInt将您的chars转换为int。比如Character.digit(value, 10)

如果我不知道,我就无法判断您是Java初学者。您似乎遵循了几乎所有的通用约定,并且总体上做得很好。没什么好抱怨的,真的。

票数 4
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/37435

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档