前两天写了一篇文章,分析了“内螺旋矩阵算法”的实现,讨论到了面向对象编程的可扩展性,于是今天用桥梁模式将代码做了些改造,具体如下:
package com.algo;
class Position {
private int x;
private int y;
public Position(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
}
/**
* 螺旋走向接口
*/
abstract class Direction {
protected StartPos startPos;
protected Position pos;// 当期的位置
protected Position periodPos;// 一个周期的开始位置
protected int max;// 行列的最大值
protected int min;// 行列的最小值
protected int len;// 方阵的阶数
private void init() {
if (startPos == null || len <= 0)
return;
Position tempPos = startPos.getPos(len);
pos = new Position(tempPos.getX(), tempPos.getY());
periodPos = new Position(tempPos.getX(), tempPos.getY());
max = len - 1;
min = 0;
}
public void setStartPos(StartPos startPos) {// 设置开始位置并重新初始化
this.startPos = startPos;
init();
}
public void setLen(int len) {// 设置长度并重新初始化
this.len = len;
init();
}
public int getLen() {
return len;
}
public Position getPos() {
int currRow = pos.getX();
int currCol = pos.getY();
Position currPos = new Position(currRow, currCol);
genNextPos();
return currPos;
}
protected abstract void genNextPos();
}
/**
* 顺时针螺旋实现
*/
class ClockwiseDir extends Direction {
protected void genNextPos() {
int row = pos.getX();
int col = pos.getY();
if (row == min && col < max) {
col++;
} else if (row < max && col == max) {
row++;
} else if (row == max && col > min) {
col--;
} else if (row > min && col == min) {
row--;
} else{
return; //匹配不到任何条件,则直接跳出(指螺旋的最后一个位置)
}
if (row == periodPos.getX() && col == periodPos.getY()) {
min++;
max--;
genNextPos();
periodPos = new Position(pos.getX(), pos.getY());
} else {
pos.setX(row);
pos.setY(col);
}
}
}
/**
* 逆时针螺旋实现
*/
class AntiClockwiseDir extends Direction {
protected void genNextPos() {
int row = pos.getX();
int col = pos.getY();
if (row == min && col > min) {
col--;
} else if (row < max && col == min) {
row++;
} else if (row == max && col < max) {
col++;
} else if (row > min && col == max) {
row--;
} else{
return; //匹配不到任何条件,则直接跳出(指螺旋的最后一个位置)
}
if (row == periodPos.getX() && col == periodPos.getY()) {
min++;
max--;
genNextPos();
periodPos = new Position(pos.getX(), pos.getY());
} else {
pos.setX(row);
pos.setY(col);
}
}
}
/**
* 螺旋起始位置接口
*/
interface StartPos {
public Position getPos(int len);
}
/**
* 起始位置为左上角的实现
*/
class TopLeft implements StartPos {
public Position getPos(int len) {
return new Position(0, 0);
}
}
/**
* 起始位置为右上角的实现
*/
class TopRight implements StartPos {
public Position getPos(int len) {
return new Position(0, len - 1);
}
}
/**
* 起始位置为左下角的实现
*/
class BottomLeft implements StartPos {
public Position getPos(int len) {
return new Position(len - 1, 0);
}
}
/**
* 起始位置为右下角的实现
*/
class BottomRight implements StartPos {
public Position getPos(int len) {
return new Position(len - 1, len - 1);
}
}
public class HelixAlgo {
public void print(Direction dir,int initVal,int step) {
int len = dir.getLen();
if (len <= 0) {
System.out.println("请输入大于0的整数!");
return;
}
int[][] helix = calculate(dir, len,initVal,step);
for (int i = 0; i < helix.length; i++) {
for (int j = 0; j < helix[i].length; j++) {
System.out.print(helix[i][j] + "\t");
}
System.out.println("");
}
}
private int[][] calculate(Direction dir, int len,int val,int step) {
int[][] helix = new int[len][len];
for (int i = 0; i < len * len; i++) {
Position pos = dir.getPos();
int row = pos.getX();
int col = pos.getY();
helix[row][col] = val;
val+=step;
}
return helix;
}
public static void main(String[] args) {
HelixAlgo algo = new HelixAlgo();
int len = 5;
Direction dir_clockwise = new ClockwiseDir();
dir_clockwise.setLen(len); //用set方法动态地插入长度
Direction dir_antiClockwise = new AntiClockwiseDir();
dir_antiClockwise.setLen(len);
System.out.println("\n左上角开始顺时针内旋(长度" + len + "):");
dir_clockwise.setStartPos(new TopLeft()); //用set方法动态地插入开始位置
algo.print(dir_clockwise,1,1);
System.out.println("\n右上角开始顺时针内旋(长度" + len + "):");
dir_clockwise.setStartPos(new TopRight());
algo.print(dir_clockwise,1,1);
System.out.println("\n右下角开始顺时针内旋(长度" + len + "):");
dir_clockwise.setStartPos(new BottomRight());
algo.print(dir_clockwise,1,1);
System.out.println("\n左下角开始顺时针内旋(长度" + len + "):");
dir_clockwise.setStartPos(new BottomLeft());
algo.print(dir_clockwise,1,1);
System.out.println("\n左上角开始逆时针内旋(长度" + len + "):");
dir_antiClockwise.setStartPos(new TopLeft());
algo.print(dir_antiClockwise,1,1);
System.out.println("\n右上角开始逆时针内旋(长度" + len + "):");
dir_antiClockwise.setStartPos(new TopRight());
algo.print(dir_antiClockwise,1,1);
System.out.println("\n右下角开始逆时针内旋(长度" + len + "):");
dir_antiClockwise.setStartPos(new BottomRight());
algo.print(dir_antiClockwise,1,1);
System.out.println("\n左下角开始逆时针内旋(长度" + len + "):");
dir_antiClockwise.setStartPos(new BottomLeft());
algo.print(dir_antiClockwise,1,1);
System.out.println("\n中心点开始顺时针外旋(长度" + len + "):");
dir_antiClockwise.setStartPos(new TopLeft());
algo.print(dir_antiClockwise,len*len,-1);
System.out.println("\n中心点开始逆时针外旋(长度" + len + "):");
dir_clockwise.setStartPos(new TopLeft());
algo.print(dir_clockwise,len*len,-1);
}
}
螺旋矩阵的解题思路就不多说了,不了解的可以看下我前面的文章“内螺旋矩阵算法分析”,这里主要说下为什么要用桥梁模式:
首先看看螺旋矩阵有哪些变化点:矩阵阶数(即边长),初始位置,和螺旋方向(顺时针,逆时针)
初始位置前面的文章在回复中已经提及,合法的初始位置只有四个既矩阵的四个角,否则会出现死胡同(可参考前面文章在10楼的回复)。
考虑到弹性,这三个变化点都应该是可以独立变化的,其中矩阵阶数只是个整数,它的变化比较方便,而另外两个可以用不同的接口封装,即上面代码的"StartPos"接口和"Direction"抽象类,这样两个变化点便可以独立的变化,因此想到了使用桥梁模式,把这两个变化点的耦合彻底移到对象层面,于是便有了mian函数中“dir_clockwise ”和“dir_antiClockwise”两个对象封装的多种输出。
其他就不多说了,代码可以运行,直接拷贝到机器上跑一下应该就明白了,有什么不足或者疑问欢迎大家一起讨论。
分享到:
相关推荐
矩阵算法题。这道题主要是类似螺旋的数字排列,从外层1旋转到最中间。 让你更加了解二维数组和矩阵的相关的应用。这里主要是一个逻辑,转过弯就容易了。想了我1天呀。很值得, 很难得,分享给大家,希望对学C的同学...
用JAVA实现螺旋矩阵的编写,这是一种比较容易让人接受的方法
c++面试题,螺旋矩阵递归算法实现及动态内存分配
对于奇数阶和偶数阶的外螺旋矩阵,分别找到他们的螺旋起点,即1的位置,依次向左、下、右、上执行由阶数决定的循环,对该位赋值为前一数值加1。
以面向对象的思想及普通算法各写了这个算法,有源代码,可以比较两种方法的区别。这样更容易了解JAVA面向对象思想的优点与便捷。
包括了分割法和自己想的标记算法 可以通过修改N的值,实现不同大小的矩阵的打印
螺旋矩阵算法对比.doc
输出螺旋矩阵的VB程序,共学习VB程序设计的复杂算法编程
有两个算法,螺旋矩阵和折线矩阵的实现,可以自己输入(n×n)矩阵的n值。
本文实例讲述了Python实现螺旋矩阵的填充算法。分享给大家供大家参考,具体如下: afanty的分析: 关于矩阵(二维数组)填充问题自己动手推推,分析下两个下表的移动规律就很容易咯。 对于螺旋矩阵,不管它是什么鬼...
主要介绍了Java实现的打印螺旋矩阵算法,结合完整实例形式详细分析了java打印螺旋矩阵的算法原理与实现技巧,需要的朋友可以参考下
实现由外向内螺旋矩阵的操作 矩阵大小为M*N 实现方法为递归调用 有完整注释,看起来比较轻松
打印输出螺旋矩阵,要求螺旋矩阵的阶数由用户输入
使用Hadoop MapReduce实现两个矩阵相乘算法
java编写的螺旋举证的程序,用了几个方向变量来控制遍历复制的方向
1.题目: n阶螺旋矩阵问题 题目描述: 创建n阶螺旋矩阵并输出。 2、阿牛的EOF牛肉串 题目描述: 今年的ACM集训队有一个叫做EOF的队伍,由阿牛、XC以及COY组 成。在共同的集训生活中,大家建立了深厚的友谊,阿牛准备做...
矩阵算法的实现,实现矩阵的大小任意控制,大学期间c++必备代码
主要介绍了PHP实现顺时针打印矩阵(螺旋矩阵)的方法,涉及PHP基于数组遍历、运算模拟打印实现螺旋矩阵功能的相关操作技巧,需要的朋友可以参考下