日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

旋转填数

發(fā)布時(shí)間:2023/12/15 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 旋转填数 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

為什么80%的碼農(nóng)都做不了架構(gòu)師?>>> ??

前兩天想起自己大二曾經(jīng)寫過的旋轉(zhuǎn)填數(shù)。就是向一個(gè)矩陣中填充數(shù)字,形成螺旋狀,比如5階的:

1????? 2?? ?? 3????? 4?? ? 5???
16??? 17??? 18??? 19??? 6???
15??? 24??? 25??? 20??? 7???
14??? 23??? 22??? 21??? 8???
13??? 12??? 11??? 10??? 9????

當(dāng)時(shí)寫的我自認(rèn)為就很不錯(cuò)了。因?yàn)槭怯眠f歸算法做的,那個(gè)年代遞歸被我們視為神技.........

今天又寫了一個(gè)版本,不過是基于OO思想的。想法是一只螞蟻從(0,0)點(diǎn)開始爬,每次遇到墻壁或者已經(jīng)爬過的地方就向右轉(zhuǎn),每到一個(gè)沒有爬過的地方就就踩一個(gè)腳印,這樣踩完以后區(qū)域也就填充完成了。個(gè)人認(rèn)為這個(gè)版本雖然代碼多,但是可讀性好,想法自然,也便于維護(hù),相比算法版本還要好玩很多。要是討論設(shè)計(jì)模式,能扯上工廠方法和策略模式....不過現(xiàn)在我對(duì)模式這種東西極為反感,寫的時(shí)候也沒有去想這些。

?

最后貼代碼:

首先是填充區(qū)域類:

package zone;import algo.*;/*** 填充區(qū)域* * @author Jeky* */ public class Zone {/*** 構(gòu)造一個(gè)新的填充區(qū)域* * @param size 填充區(qū)域大小*/public Zone(int size) {this.size = size;board = new int[size][size];}/*** 以特定值填充某個(gè)位置* * @param p 位置* @param value 值*/public void fill(Point p, int value) {board[p.getX()][p.getY()] = value;}/*** 以特定值填充某個(gè)位置* * @param x 橫坐標(biāo)* @param y 縱坐標(biāo)* @param value 值*/public void fill(int x, int y, int value) {board[x][y] = value;}/*** 獲取某個(gè)特定位置的值* * @param p 位置* @return 值*/public int get(Point p) {return board[p.getX()][p.getY()];}/*** 獲取某個(gè)特定位置的值* * @param x 橫坐標(biāo)* @param y 縱坐標(biāo)* @return 值*/public int get(int x, int y) {return board[x][y];}/*** 獲取區(qū)域大小* * @return 區(qū)域大小*/public int getSize() {return size;}@Overridepublic String toString() {StringBuilder sb = new StringBuilder();for (int i = 0; i < size; i++) {for (int j = 0; j < size; j++) {sb.append(board[j][i] + "\t");}sb.append("\n");}return sb.toString();}private final int size;private int[][] board; }

坐標(biāo)點(diǎn):

package zone;/*** 二維位置* * @author Jeky* */ public class Point {/*** 以橫縱坐標(biāo)構(gòu)造一個(gè)新的位置* * @param x 橫坐標(biāo)* @param y 縱坐標(biāo)*/public Point(int x, int y) {super();this.x = x;this.y = y;}/*** 獲得橫坐標(biāo)* * @return 橫坐標(biāo)*/public int getX() {return x;}/*** 獲得縱坐標(biāo)* * @return 縱坐標(biāo)*/public int getY() {return y;}@Overridepublic String toString() {return "(" + x + "," + y + ")";}private final int x;private final int y; }

填充接口:

package algo;import zone.Zone;/*** 旋轉(zhuǎn)填數(shù)接口* * @author Jeky* */ public interface ZoneFiller {/*** 向區(qū)域填充數(shù)據(jù)* * @param zone 填充區(qū)域*/void fill(Zone zone); }

遞歸填充算法:

?

package algo;import zone.Zone;/*** 以遞歸模式進(jìn)行填充的填充類* * @author Jeky* */ public class RecursionFiller implements ZoneFiller {@Overridepublic void fill(Zone zone) {int size = zone.getSize();this.zone = zone;fill(1, size, 0, 0);}/*** 進(jìn)行遞歸填充* * @param startNumber 開始數(shù)字* @param size 填充長度* @param startX 填充開始橫坐標(biāo)* @param startY 填充開始縱坐標(biāo)*/private void fill(int startNumber, int size, int startX, int startY) {if (size == 0) {return;} else if (size == 1) {zone.fill(startX, startY, startNumber);} else {for (int i = startX; i < size + startX - 1; i++) {zone.fill(i, startY, startNumber);startNumber++;}for (int i = startY; i < size + startY - 1; i++) {zone.fill(startX + size - 1, i, startNumber);startNumber++;}for (int i = startX + size - 1; i >= 1 + startX; i--) {zone.fill(i, startY + size - 1, startNumber);startNumber++;}for (int i = startY + size - 1; i >= 1 + startY; i--) {zone.fill(startX, i, startNumber);startNumber++;}fill(startNumber, size - 2, startX + 1, startY + 1);}}private Zone zone; }

螞蟻填充算法:

?

package algo;import zone.Point; import zone.Zone;/*** 螞蟻類,負(fù)責(zé)在填充區(qū)域上爬行并踩出記號(hào)* * @author Jeky* */ public class Ant implements ZoneFiller{public Ant() {movements = new Movement[4];movements[0] = new RightMovement();movements[1] = new DownMovement();movements[2] = new LeftMovement();movements[3] = new UpMovement();nowMovementIndex = 0;}/*** 爬行并踩出記號(hào)* * @param zone 填充區(qū)域*/public void fill(Zone zone) {footPrint = 1;location = new Point(0, 0);tread(zone);int maxPrint = zone.getSize() * zone.getSize();while (footPrint <= maxPrint) {Point nextLocation = getNextLocation();if (canWalkTo(zone, nextLocation)) {location = nextLocation;tread(zone);} else {changeDirection();}}}/*** 踩出記號(hào)* * @param zone 填充區(qū)域*/private void tread(Zone zone) {zone.fill(location, footPrint);footPrint++;}/*** 獲取下一個(gè)要爬行到的位置* * @return 下一個(gè)爬行到的位置*/private Point getNextLocation() {Movement m = movements[nowMovementIndex];return m.getNextPoint(location);}/*** 是否可以向前爬行* * @param zone 填充區(qū)域* @param p 前面的位置* @return 如果可以向前,返回true,否則返回false*/private boolean canWalkTo(Zone zone, Point p) {return p.getX() >= 0&& p.getY() >= 0&& p.getX() < zone.getSize()&& p.getY() < zone.getSize()&& zone.get(p) == 0;}/*** 換方向*/private void changeDirection() {nowMovementIndex = (nowMovementIndex + 1) % 4;}/*** 爬行動(dòng)作*/private interface Movement {Point getNextPoint(Point p);}/*** 向上爬*/private class UpMovement implements Movement {@Overridepublic Point getNextPoint(Point p) {return new Point(p.getX(), p.getY() - 1);}}/*** 向下爬*/private class DownMovement implements Movement {@Overridepublic Point getNextPoint(Point p) {return new Point(p.getX(), p.getY() + 1);}}/*** 向左爬*/private class LeftMovement implements Movement {@Overridepublic Point getNextPoint(Point p) {return new Point(p.getX() - 1, p.getY());}}/*** 向右爬*/private class RightMovement implements Movement {@Overridepublic Point getNextPoint(Point p) {return new Point(p.getX() + 1, p.getY());}}private Movement[] movements;private int nowMovementIndex;private int footPrint;private Point location; }

轉(zhuǎn)載于:https://my.oschina.net/Jeky/blog/28757

總結(jié)

以上是生活随笔為你收集整理的旋转填数的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。