BJFU Java程序设计实验二——方阵遍历

一、实验要求

  1. 抽象类、上转型、方法重写、运行时多态等知识要点。
  2. 熟悉抽象编程和框架编程的方法。
  3. 掌握复杂条件判断的编程方法。
  4. 实验实现目标:编写一个抽象类,该类实现了方阵遍历的一般框架,实现了遍历和显示的大部分方法。继承这个抽象类,实现4个具体类(其中一个作为例子已经给出),实现它们分别的任意规模的方阵遍历。

二、实验内容和步骤

1.实验背景介绍

(1)方阵的行数和列数相等,遍历方阵的方式方法有很多,包括列主序、行主序、对角遍历、反对角遍历、顺时针遍历、逆时针遍历等等。

(2)首先实现一个抽象类,实现这些遍历方式的共同点和共同功能。

(3)继承抽象类,实现所有具体类,并加以测试。

2.用记事本书写一个Java程序

(1)、建立个人子目录

步骤1:建立个人子目录

第一次上机时先在D盘上建立一个以自己学号+姓名为目录名的子目录,如学号为210824109的张三同学,就用“210824109张三”为子目录名。实验完成的源代码、Java字节码和实验报告三个文件都要放在这个文件夹下(称为上交文件夹)。

步骤2:建立Java源代码文件

在所建立的文件夹下建立一个记事本文件SquarePoint.txt, SquareTraversal.txt, RowMajor.txt, ColMajor.txt, Diagonal.txt, AntiDiagonal.txt, SquareTraversalApplication.txt,并把它重命名为SquarePoint.java, SquareTraversal.java, RowMajor.java, ColMajor.java, Diagonal.java, AntiDiagonal.java, SquareTraversalApplication.java,

(2)、编写源代码

步骤1:创建7个公共类SquarePoint, SquareTraversal, RowMajor, ColMajor, Diagonal, AntiDiagonal, SquareTraversalApplication.

要创建的公共类在exp1包中,可引入其它的包。所创建的7个公共类在文件中的一行如下:

public class SquarePoint{… …}

public class SquareTraversal {… …}

……

步骤2:建立主方法main( )

在类SquareTraversalApplication的类体中编写主方法:

public static void main(String[] args){… …}

步骤3:编写各类的方法和SquareTraversalApplication主方法main( )

主方法用于测试。各个类都已经给出了部分代码,请参考附件。

3.调试和运行

(1)、调试

步骤1:使用命令行工具,先进入用所建的目录下。参见图1。

步骤2:用javac exp2/SquareTraversalApplication.java编译并调试源代码文件。参见图1。

(2)、运行

使用java exp2.Fraction运行程序。参见文件最后的运行结果。

运行说明:路径每产生一个节点都要打印一次,不要等到所有路径产生之后再打印。

//文件 AntiDiagonal.java
package exp2;

/*
 * 本类实现反对角方式的方阵遍历:
 */
public class AntiDiagonal extends SquareTraversal {

    public AntiDiagonal(int size) {
        initiate(size);
    }

    @Override public SquarePoint getInitPoint() {
        return new SquarePoint(0, 0);
    }

    @Override public SquarePoint getNext() {
        // Add your code here
        SquarePoint currentPoint = currentPath.get(currentPath.size() - 1);
        int currRow = currentPoint.getRow();
        int currCol = currentPoint.getCol();
        int nextRow = currRow;
        int nextCol = currCol;
        if(currRow == size - 1 && currCol == size - 1)
        {
            return null;
        }
        else if(currRow > 0 && currCol < size - 1)
        {
            nextCol = currCol + 1;
            nextRow = currRow - 1;
        }
        else if(currCol == size -1 && currRow == 0)
        {
            nextCol = 1;
            nextRow = size - 1;
        }
        else if(currRow == 0)
        {
            nextCol = currRow;
            nextRow = currCol + 1;
        }
        else if(currCol == size - 1)
        {
            nextCol = currRow + 1;
            nextRow = currCol;
        }
        return new SquarePoint(nextRow, nextCol);
    }

}
// 文件ColMajor.java
package exp2;

/*
 * 本类实现列主序的方阵遍历方式。
 */
public class ColMajor extends SquareTraversal {
    public ColMajor(int size) {
        initiate(size);
    }

    @Override public SquarePoint getInitPoint() {
        return new SquarePoint(0, 0);
    }

    @Override public SquarePoint getNext() {
        // Add your code here
        SquarePoint currentPoint = currentPath.get(currentPath.size() - 1);
        int currRow = currentPoint.getRow();
        int currCol = currentPoint.getCol();
        int nextRow = currRow;
        int nextCol = currCol;
        if (currRow < size-1) {
            nextRow = currRow + 1;
        }
        else {
            if (currCol == size-1) {
                return null;
            }
            else {
                nextCol = currCol + 1;
                nextRow = 0;
            }
        }
        return new SquarePoint(nextRow, nextCol);
    }
}
// 文件Diagonal.java
package exp2;

/*
 * 本类实现对角方式的方阵遍历。
 */
public class Diagonal extends SquareTraversal {
    public Diagonal(int size) {
        initiate(size);
    }

    @Override
    public SquarePoint getInitPoint() {
        return new SquarePoint(size - 1, 0);
    }

    @Override
    public SquarePoint getNext() {
        SquarePoint currentPoint = currentPath.get(currentPath.size() - 1);
        int currRow = currentPoint.getRow();
        int currCol = currentPoint.getCol();
        int nextRow = currRow;
        int nextCol = currCol;
        if(currCol == size - 1 && currRow == 0)
        {
            return null;
        }
        else if(currCol < size - 1 && currRow < size - 1)
        {
            nextCol = currCol + 1;
            nextRow = currRow + 1;
        }
        else if(currRow == size - 1 && currCol == size - 1)
        {
            nextCol = 1;
            nextRow = 0;
        }
        else if(currRow == size - 1)
        {
            nextCol = size - 1 - currRow;
            nextRow = size - 1 - currCol - 1;
        }
        else if(currCol == size - 1)
        {
            nextCol = size - 1 - currRow + 1;
            nextRow = size - 1 - currCol;
        }
        return new SquarePoint(nextRow, nextCol);
    }
}
// 文件RowMajor.java
package exp2;

/*
 * 本类实现行主序的方阵遍历。
 */
public class RowMajor extends SquareTraversal {
    public RowMajor(int size) {
        initiate(size);
    }

    @Override public SquarePoint getInitPoint() {
        return new SquarePoint(0, 0);
    }

    @Override public SquarePoint getNext() {
        SquarePoint currentPoint = currentPath.get(currentPath.size() - 1);
        int currRow = currentPoint.getRow();
        int currCol = currentPoint.getCol();
        int nextRow = currRow;
        int nextCol = currCol;
        if (currCol < size-1) {
            nextCol = currCol + 1;
        }
        else {
            if (currRow == size-1) {
                return null;
            }
            else {
                nextRow = currRow + 1;
                nextCol = 0;
            }
        }
        return new SquarePoint(nextRow, nextCol);
    }
}

//文件SquarePoint.java
package exp2;

/*
 * 本类对象表示方阵中的一个点。一个点由行和列两个坐标表示。
 * 最上方的行号最小,为0;最左边的列号最小,为0。
 */
public class SquarePoint {
    int row = 0;
    int col = 0;
    public SquarePoint() { }
    public SquarePoint(int row, int col) {
        this.row = row;
        this.col = col;
    }
    public void setRow(int row) {
        this.row = row;
    }
    public void setCol(int col) {
        this.col = col;
    }
    public int getRow() {
        return row;
    }
    public int getCol() {
        return col;
    }

    @Override public String toString() {
        return "(" + row + "," + col + ")";
    }
}

//文件SquareTraversal.java
package exp2;

import java.util.ArrayList;

/*
 * 这是一个抽象类,对任何一种遍历方阵的方法给出了整体的框架。
 * 已经实现了遍历的关键步骤和打印输出的主要功能。
 * 两个可变的方法需要用户实现,以适应不同的需求。
 */
public abstract class SquareTraversal {
    // 方阵的规模,用size表示方阵的边长:
    int size = -1; //一开始强制为-1,容易在子类运行中暴露没有初始化的问题。

    // 获取遍历的初始点。使用抽象方法的意义是:强迫用户实现这个方法,而不至于遗漏。这个方法千万不可实现(最简单的实现那种),否则,最终用户很难发现问题所在。
    public abstract SquarePoint getInitPoint();

    // 遍历过程中当前的路径:
    ArrayList<SquarePoint> currentPath = new ArrayList<>();

    // 方阵初始化:size表示方阵的大小;initRow和initCol表示路径的起始位置:
    public void initiate(int size) {
        this.size = size; //这一句话和下一条语句千万不能颠倒,否则是一个打错。
        SquarePoint initPoint = getInitPoint(); //只有使用上一句中赋值的size才是正确的。
        currentPath.add(initPoint);
    }

    // 查找下一个点。
    // 如果存下一个点,则返回这个点;否则返回null。
    // 这个方法交给具体的类按照自己的场景去实现:
    public abstract SquarePoint getNext();

    // 路径推进一步(该步骤的执行之前先要判断是否存在可行的下一步):
    public void step(SquarePoint nextPoint) {
        currentPath.add(nextPoint); // 一条语句就可以实现这个功能。
    }

    @Override
    public String toString() {
        return "size: " + size + "; currentPath: " + currentPath;
    }

    String str [][] = new String[10][10];
    public void Initstr()
    {
        for(int i=0;i<10;i++)
            for(int j=0;j<10;j++)
                str[i][j] = "-";
    }
    // 这个方法打印当前路径在整个方阵中的分布情况。
// 没有遍历过的点用减号表示;已经遍历过的点用加号表示;当前遍历点(最后一个点)用星号表示,以突出其变化:
// 具体实现留给同学们自己实现,打印格式轻参看附件的结果输出。
    public void printCurrentPath() {
        // Add your code here
        SquarePoint currentPoint = currentPath.get(currentPath.size() - 1);
        int currRow = currentPoint.getRow();
        int currCol = currentPoint.getCol();
        str[currRow][currCol] = "*";
        String all = "";

        for(int i=0;i<size;i++)
        {
            for(int j=0;j<size;j++)
            {
                all += str[i][j];
            }
            System.out.println(all);
            all = "";
        }
        str[currRow][currCol] = "+";
    }

    // 用这个方法执行遍历的全过程。每遍历一步,都要打出路径的整体分布情况。
    public void traverse() {
        Initstr();
        printCurrentPath();
        System.out.println();
        SquarePoint nextPoint = null;
        while ((nextPoint = getNext()) != null) {
            step(nextPoint);
            printCurrentPath();
            System.out.println();
        }
        System.out.println("The whole path is : " + currentPath);
        System.out.println();
    }
}

// 文件SquareTraversalApplication.java
package exp2;

/*
 * 本类用来规模化测试抽象类下的每一个具体类的遍历情况。
 */
public class SquareTraversalApplication {
    public static void main(String[] args) {
        exp2.SquareTraversal[] squareTraversals = new exp2.SquareTraversal[4];
        int[] sizes = {3, 3, 5, 4};
        String[] names = {"行主序", "列主序", "反对角", "对角"};
        squareTraversals[0] = new exp2.RowMajor(sizes[0]);
        squareTraversals[1] = new exp2.ColMajor(sizes[1]);
        squareTraversals[2] = new exp2.AntiDiagonal(sizes[2]);
        squareTraversals[3] = new exp2.Diagonal(sizes[3]);
        for (int i=0; i<squareTraversals.length; i++) {
            System.out.println(names[i] + ", size: " + sizes[i]);
            squareTraversals[i].traverse();
        }
    }
}
  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值