2013-09-29 45 views
0

我正在研究一个检查数独解决方案的有效性的程序。我已经接近完成了,但由于某种原因,当我尝试调用某些已创建的方法时,编译器会返回它们未定义的方法。泛型和在实现Iterable接口的类中使用新创建的方法

有三种主要类型:

  1. 数独类,它实现了可迭代接口。它包含一个二维数组,就是难题。构造函数从扫描仪输入中获取文件并构建难题。它有一个迭代器方法来满足接口要求。此方法返回类型为SudokuIterator的interator。

  2. SudokuIterator类,它实现了Iterator接口。这是Sudoku类的私人内部类。它也有一个2维数组和一个光标作为属性。它有标准的hasNext(),next()和一个remove()存根来满足接口。我还添加了一个nextColumn()和nextBox(),它根据光标位置返回一个数组。下一个方法已被覆盖返回行。

  3. 最后是Validator。这种方法是主要的方法。它有一个方法isSolution(),它返回一个布尔值,取决于从SudokuIterator类中定义的方法返回的每个数组的分析。

这是我的问题出现的地方;当使用迭代器方法实例化并返回一个SudokuIterator并尝试使用添加的nextColumn()和nextBox()方法时,编译器会返回这些方法未定义为Iterator。

任何意见或建议将不胜感激。提前致谢。

import java.util.*; 

/** 
* Sudoku class represents the matrix of cells in a Sudoku puzzle 
* @version 01/05/2012 
* @author Bob Wilson 
*/ 

public class Sudoku implements Iterable<Cell []> 
{ 
    private Cell [] [] puzzle; 

    /** 
    * Default constructor should not be called. Make it private. 
    */ 
    private Sudoku() {} 

    /** 
    * Puzzle constructor that uses a Scanner object to read a file. 
    * File contains 81 numbers that are the values of the 81 cells. 
    * @param file a Scanner object on a File object 
    */ 
    public Sudoku(Scanner file) 
    { 
    int size = file.nextInt(); 
    System.out.println("Size: " + size); 
    puzzle = new Cell[size][size]; 
    for (int i = 0; i < size; i++) 
     for (int j = 0; j < size; j++) 
     puzzle[i][j] = new Cell(file.nextInt()); 
    } 

    public int getLength(){ 
     return this.puzzle.length; 
    } 


    class SudokuIterator implements Iterator<Cell []> { 

     private Cell [][] puzzle; 
     private int cursor; 

     public SudokuIterator(Cell [][] puzzle){ 

      this.puzzle = puzzle; 
      cursor = 1; 

     } 


     public boolean hasNext(){ 
      if(cursor <= this.puzzle.length){ 
       return true; 
      } 
      return false; 
    } 
     public Cell[] next(){ 
      Cell[] row = puzzle[cursor-1]; 
      cursor++; 
      return row; 
     } 

     public Cell[] nextColumn(){ 
      Cell[] column = new Cell[puzzle.length]; 
      for(int i = 0; i < puzzle.length; i++){ 
       column[i] = puzzle[i][cursor-1]; 
      } 
      cursor++; 
      return column; 
     } 

     public Cell[] nextBox(){ 
      Cell[] box = new Cell[puzzle.length]; 
      int boxIndex = 0; 
      for(int i = ((cursor - 1)/((int)Math.sqrt(puzzle.length)))*(int)Math.sqrt(puzzle.length) ; i < ((cursor - 1)/((int)Math.sqrt(puzzle.length)))*(int)Math.sqrt(puzzle.length) + (int)Math.sqrt(puzzle.length); i++){ 
       for(int j = (((cursor - 1) + ((int)Math.sqrt(puzzle.length))) % ((int)Math.sqrt(puzzle.length))) * ((int)Math.sqrt(puzzle.length)); j < (((cursor - 1) + ((int)Math.sqrt(puzzle.length))) % ((int)Math.sqrt(puzzle.length))) * ((int)Math.sqrt(puzzle.length)) + ((int)Math.sqrt(puzzle.length)); j++){ 
        box[boxIndex] = puzzle[i][j]; 
       } 
      } 
      cursor++; 
      return box; 
     } 
     public void remove(){} 
    } 
    /** 
    * Generates and returns a String representation of the puzzle cells 
    * @return A String representing the contents of the puzzle array 
    */ 
    public String toString() 
    { 
    // display the puzzle 
    String value = "Puzzle is:\n"; 

    for (int i = 0; i < puzzle.length; i++) { 
     for (int j = 0; j < puzzle[i].length; j++) 
     value += puzzle[i][j].toString(); 
     value += "\n"; 
    } 
    return value; 
    } 

    /** 
    * Instantiates and returns a new SudokuIterator object 
    * @return A SudokuIterator object on the puzzle array 
    */ 

    public SudokuIterator iterator(){ 

    SudokuIterator iterator = new SudokuIterator(this.puzzle); 
    return iterator; 

    } 


    } 
    /* 201340 */ 

import java.util.*; 
import java.io.*; 

/** 
* This class instantiates a Sudoku object passing a Scanner on a 
* file to the Sudoku constructor. It prints the puzzle using the 
* Sudoku toString method. It determines if the digit matrix is a 
* valid solution for a Sudoku puzzle or not and prints the result. 
* 
* @version 01/05/2012 
* @author Bob Wilson 
* 
*/ 

public class SudokuValidator 
{ 
    private Sudoku puzzle; 

    /** 
    * @param args - not used 
    */ 
    public static void main(String [] args) 
    { 
    Scanner scan = new Scanner(System.in); 
    System.out.println("Please enter name of file containing puzzle to verify"); 
    SudokuValidator myValidator = new SudokuValidator(scan.nextLine()); 
    System.out.println(myValidator.isSolution()); 
    } 

    public SudokuValidator(String fileName) 
    { 
    Scanner file = null; 
    try 
    { 
     file = new Scanner(new File(fileName)); 
    } 
    catch (Exception e) 
    { 
     System.out.println("Bad file name"); 
     System.exit(0); 
    } 

    puzzle = new Sudoku(file); 
    System.out.println(puzzle); 
    } 

    public boolean isSolution(){ 


     boolean flag = true; 
     Iterator<Cell[]> game = puzzle.iterator(); 

     while(game.hasNext()){ 
      Cell[] row = game.next(); 
      Cell[] column = game.nextColumn(); 
      Cell[] box = game.nextBox(); 


      for(Cell i: row){ 
       for(Cell j: row){ 
        if(j.equals(i.getValue())){ 
         flag = false; 
         return flag; 
        } 
       } 
      } 
     } 
     return flag; 
    } 
} /* 201340 */ 

回答

3

的问题是,所声明的类型game参考变量的是Iterator,它没有定义任何nextColumn()方法,所以编译器无法找到它。您可以通过将声明的类型更改为Sudoku.SudokuIterator(因为这是一个内部类)来解决此问题。

变化:

Iterator<Cell[]> game = puzzle.iterator(); 

到:

Sudoku.SudokuIterator game = puzzle.iterator(); 
+0

现在我得到一个编译错误说: “SudokuIterator不能被解析为一个类型。” – Atache

+0

@Atache。添加一个导入到你的班级。 –

+0

@Atache。如果你有你的类在默认包,这是非常糟糕的,然后更改引用类型为'Sudoku.SudokuIterator' –