阅读 78660 次
发表时间:2009-12-15
既然是java题,个人觉得用面向对象的方式来实现比较好,比如这里可以看做是贪吃蛇游戏的简化版。
这个蛇的操作有游走、打印足迹,另外还可以记录足迹、碰到墙壁和走过的地方会掉头。
其他的对象就是点Point和方向Direction。其中方向Direction 有四个子类分别是:上下左右。
因为方向是固定的,先右-》下-》左-》上,可以通过next方法获得掉头后的Direction
class Point {//坐标上的点
 int x;
        int y;
        String value;
        Direction dir;//这个点的方向
}
abstract Direction {
     int size;
    
     abstract Direction next();//下一个方向
     abstract nextPoint(Point point,Map map);//如果在本方向上越界或者已经走过就调头,否则本方向上取下一个点
}
class Snake{
    int size;//=6
    Map map;//走过的点
    public void run() {}//初始化起始点和起始方向,遍历size*size次,把走过的点放在map中。
    public void print(){}//根据矩阵遍历map对象
    public void main(String[]args) {
            Snake sn = new Snake(6);
           sn.run();
           sn.print();
   }
}
chinpom 写道

看一下我的,思路应该更清晰一点:

public class SnakePrint {

	private int orient = 0, length = 0, x = 0, y = 0;
	// orients为顺时针90°旋转方向,前进步长为1
	private int[][] orients = { { 0, 1 }, { 1, 0 }, { 0, -1 }, { -1, 0 } };
	private int[][] arrays;

	public SnakePrint(int length) {
		this.length = length;
		arrays = new int[length][length];
	}

	// 根据当前方向返回下一个前进方向
	private int[] nextOrient(int[] curOrient) {
		int nextX = x + curOrient[0], nextY = y + curOrient[1];

		// 前进方向需要顺时针旋转90°了
		if (nextX < 0 || nextX >= length || nextY < 0 || nextY >= length
				|| arrays[nextX][nextY] != 0) {
			orient = ++orient % 4;
			return orients[orient];
		}

		return curOrient; // 不需要掉头,返回原前进方向
	}

	public void print() {
		int[] curOrient = orients[orient]; // 初始前进方向
		for (int i = 1; i <= length * length; i++) { // 依次填充数组
			arrays[x][y] = i;
			curOrient = nextOrient(curOrient);
			x += curOrient[0];
			y += curOrient[1];
		}

		for (int i = 0; i < length; i++) {
			for (int j = 0; j < length; j++) {
				System.out.printf("%4d", arrays[i][j]); // 按固定4个字符宽度的格式输出
			}
			System.out.println();
		}
	}

	public static void main(String[] args) {
		SnakePrint snakePrint = new SnakePrint(6);
		snakePrint.print();
	}
}
 

 

发表时间:2009-12-15
真的是想研究模的 只是失败了


    @Test
    public void snake() {
        assertEquals(1, mod(0, 0, 6));
        assertEquals(7, mod(5, 1, 6));
        assertEquals(20, mod(0, 1, 6));
        assertEquals(16, mod(0, 5, 6));
        assertEquals(11, mod(5, 5, 6));
        assertEquals(33, mod(2, 2, 6));
        assertEquals(26, mod(4, 3, 6));

        //after all test passed!
        int printSize = 7;
        
        for(int i=0;i<printSize;i++){
            for(int j=0;j<printSize;j++)
                System.out.printf("%4d",mod(j,i,printSize));
            System.out.println();
        }

    }
    
    private int[][] bufData;
    private int mylength;

    private int mod(int x, int y, int n) {
        if (bufData == null || mylength != n) {
            int dilength = n / 2 + n % 2;
            bufData = new int[n][n];
            int di = 0;
            int number = 0;
            while (di < dilength) {
                //单一维度的打印
                int j = 0;
                int k = 0;

                //->   y=di   x [ di -> n-di ]
                k = di;
                for (j = di; j < n - di; j++) {
                    bufData[j][k] = ++number;
                }
                //|  x = n-di  y [di+1 -> n-di]
                j = n - di -1;
                for (k = di + 1; k < n - di; k++) {
                    bufData[j][k] = ++number;
                }
                //<-  y=n-di x [n-di-1 -> di]
                k = n - di -1;
                for (j = n - di - 1 - 1; j >= di; j--) {
                    bufData[j][k] = ++number;
                }
                //|  x = di y [ n-di-1 -> di ]
                j = di;
                for (k = n - di - 1 - 1; k > di; k--) {
                    bufData[j][k] = ++number;
                }

                //END
                di++;
            }
        }
        return bufData[x][y];
    }
发表时间:2009-12-15
本来在问答里答的,居然发现已经有讨论了。我帖上我的,花了一个小时的。
思路就是从0开始,判断其下一个数字的位置,依次判断周围四个数字然后选择正确的数字。
public class Test {
	static int n = 10;
	static int[][] arr = new int[n][n];

	public static void main(String[] args) {
		int x = 0, y = 0;
		for (int i = 1; i <= n * n; i++) {
			arr[x][y] = i;
			if (canSet(x + 1, y) && !canSet(x, y - 1)) {
				x = x + 1;
			} else if (canSet(x, y + 1) && !canSet(x + 1, y)) {
				y = y + 1;
			} else if (canSet(x - 1, y) && !canSet(x, y + 1)) {
				x = x - 1;
			} else if (canSet(x, y - 1) && !canSet(x - 1, y)) {
				y = y - 1;
			}
		}
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				System.out.print(arr[j][i] + " ");
			}
			System.out.println("");
		}
	}

	private static boolean canSet(int x, int y) {
		if (x < 0 || y < 0 || x >= n || y >= n)
			return false;
		if (arr[x][y] != 0)
			return false;
		return true;
	}
}
发表时间:2009-12-15
就是递归打印个正方形嘛...
搞的这么麻烦
发表时间:2009-12-15
import java.util.HashMap;
import java.util.Map;



class Point {
	private int x;
	private int y;
	private String val;
	
	public Point (int x,int y) {
		this.x = x;
		this.y = y;
	}
	
	public Point (int x, int y, String val) {
		this(x, y);
		this.val = val;
	}

	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;
	}

	public String getVal() {
		return val;
	}

	public void setVal(String val) {
		this.val = val;
	}
	
}

abstract class Direction {
	int size;
	abstract public Point nextPoint(Point p);//下个点
	abstract public Direction next();//下一个方向
	abstract public boolean isOut(Point point);//是否在本方向上出界
	
}


class Right extends Direction {
	public Right(int size){
		this.size = size;
	}
	public Direction next() {
		return new Down(size);
	}
	public Point nextPoint(Point p) {
		return new Point(p.getX() + 1,p.getY());
	}
	public boolean isOut(Point point) {
		return point.getX() > size;
	}
}

class Down extends Direction {
	
	public Down(int size){
		this.size = size;
	}
	public Direction next() {
		return new Left(size);
	}
	public Point nextPoint(Point p) {
		return new Point(p.getX(),p.getY() + 1);
	}
	public boolean isOut(Point point) {
		return point.getY() > size;
	}
}
class Left extends Direction {
	public Left(int size){
		this.size = size;
	}
	public Direction next() {
		return new Up(size);
	}
	public Point nextPoint(Point p) {
		return new Point(p.getX() - 1,p.getY());
	}
	public boolean isOut(Point point) {
		return point.getX() < 1;
	}
}
class Up extends Direction {
	public Up(int size){
		this.size = size;
	}
	public Direction next() {
		return new Right(size);
	}
	public Point nextPoint(Point p) {
		return new Point(p.getX(),p.getY()-1);
	}
	public boolean isOut(Point point) {
		return point.getY() < 1;
	}
}
public class Snake {
	
	int size;
	
	Map<String ,Point> map = new HashMap<String, Point>();//记录走过的点
	
	public Snake(int size) {
		this.size = size;
	}
	
	public void run() {
		Point next = new Point(1, 1,"1");
		Direction dirct = new Right(size);
		map.put(key(1,1), next);
		for(int i = 2; i < size * size + 1; i++) {
			Point tempNext = dirct.nextPoint(next);
			//如果在一个方向上出界或者已经走过的点要掉头
			if(dirct.isOut(tempNext) || null != map.get(key(tempNext.getX(),tempNext.getY()))) {
				dirct = dirct.next();
				next = dirct.nextPoint(next);
			}
			else {
				next = tempNext;
			}
			next.setVal(String.valueOf(i));
			map.put(key(next.getX(),next.getY()), next);//记录走过的点
		}
	}
	
	//生成key
	private String key(int x,int y) {
		String xVal = "00000" + x;
		String yVal = "00000" + y;
		return xVal.substring(xVal.length()-3) + yVal.substring(yVal.length() - 3);
	}
	
	public void print() {
		for (int y = 1; y < size + 1 ; y++) {
			for(int x = 1; x < size + 1; x++) {
				String temp = "     " + map.get(key(x,y)).getVal();
				System.out.print(temp.substring(temp.length() - 5));
			}
			System.out.println("");
		}
	}
	
	public static void main(String[] args) {
		Snake sn = new Snake(25);
		sn.run();
		sn.print();
	}

}

     1    2    3    4    5    6    7    8    9   10   11   12   13   14   15   16   17   18   19   20   21   22   23   24   25
   96   97   98   99  100  101  102  103  104  105  106  107  108  109  110  111  112  113  114  115  116  117  118  119   26
   95  184  185  186  187  188  189  190  191  192  193  194  195  196  197  198  199  200  201  202  203  204  205  120   27
   94  183  264  265  266  267  268  269  270  271  272  273  274  275  276  277  278  279  280  281  282  283  206  121   28
   93  182  263  336  337  338  339  340  341  342  343  344  345  346  347  348  349  350  351  352  353  284  207  122   29
   92  181  262  335  400  401  402  403  404  405  406  407  408  409  410  411  412  413  414  415  354  285  208  123   30
   91  180  261  334  399  456  457  458  459  460  461  462  463  464  465  466  467  468  469  416  355  286  209  124   31
   90  179  260  333  398  455  504  505  506  507  508  509  510  511  512  513  514  515  470  417  356  287  210  125   32
   89  178  259  332  397  454  503  544  545  546  547  548  549  550  551  552  553  516  471  418  357  288  211  126   33
   88  177  258  331  396  453  502  543  576  577  578  579  580  581  582  583  554  517  472  419  358  289  212  127   34
   87  176  257  330  395  452  501  542  575  600  601  602  603  604  605  584  555  518  473  420  359  290  213  128   35
   86  175  256  329  394  451  500  541  574  599  616  617  618  619  606  585  556  519  474  421  360  291  214  129   36
   85  174  255  328  393  450  499  540  573  598  615  624  625  620  607  586  557  520  475  422  361  292  215  130   37
   84  173  254  327  392  449  498  539  572  597  614  623  622  621  608  587  558  521  476  423  362  293  216  131   38
   83  172  253  326  391  448  497  538  571  596  613  612  611  610  609  588  559  522  477  424  363  294  217  132   39
   82  171  252  325  390  447  496  537  570  595  594  593  592  591  590  589  560  523  478  425  364  295  218  133   40
   81  170  251  324  389  446  495  536  569  568  567  566  565  564  563  562  561  524  479  426  365  296  219  134   41
   80  169  250  323  388  445  494  535  534  533  532  531  530  529  528  527  526  525  480  427  366  297  220  135   42
   79  168  249  322  387  444  493  492  491  490  489  488  487  486  485  484  483  482  481  428  367  298  221  136   43
   78  167  248  321  386  443  442  441  440  439  438  437  436  435  434  433  432  431  430  429  368  299  222  137   44
   77  166  247  320  385  384  383  382  381  380  379  378  377  376  375  374  373  372  371  370  369  300  223  138   45
   76  165  246  319  318  317  316  315  314  313  312  311  310  309  308  307  306  305  304  303  302  301  224  139   46
   75  164  245  244  243  242  241  240  239  238  237  236  235  234  233  232  231  230  229  228  227  226  225  140   47
   74  163  162  161  160  159  158  157  156  155  154  153  152  151  150  149  148  147  146  145  144  143  142  141   48
   73   72   71   70   69   68   67   66   65   64   63   62   61   60   59   58   57   56   55   54   53   52   51   50   49

发表时间:2009-12-16
mod获得位置输出的么
发表时间:2009-12-16
谈点体会,也碰过这类面试题,也许人家想考察我们对面向对象的分析和设计而
不是具体的算法实现,当我画出类图或者类定义等,面试官总很不屑,很受打击。
我想具体的实现工作做可以参考资料就OK了。但也有些面试官水平(思维)有限只看你是否写出算法。
其实,如果给出具体的算法,像有些网友贴出来的都能实现,但面试官真的有时间有心情还要仔细读才能看懂。


我也当过面试官,我一般问在工作中对面向对象有什么体会,如何应用到具体的工作中和工作态度。一般对具体的技术不会深入
提问,我觉得一个人如果能理解面向对象思想了,对于具体的技术只要有机会用到,用心去学,没有学不会的!




发表时间:2009-12-16
ilove2009 写道
谈点体会,也碰过这类面试题,也许人家想考察我们对面向对象的分析和设计而
不是具体的算法实现,当我画出类图或者类定义等,面试官总很不屑,很受打击。
我想具体的实现工作做可以参考资料就OK了。但也有些面试官水平(思维)有限只看你是否写出算法。
其实,如果给出具体的算法,像有些网友贴出来的都能实现,但面试官真的有时间有心情还要仔细读才能看懂。


我也当过面试官,我一般问在工作中对面向对象有什么体会,如何应用到具体的工作中和工作态度。一般对具体的技术不会深入
提问,我觉得一个人如果能理解面向对象思想了,对于具体的技术只要有机会用到,用心去学,没有学不会的!






很是同意,有的时候只要有想法和思路就OK了,学的再多,再精通,工作上没有用到,还是没有多大用处!
当然对你分析代码和看问题有帮助!
发表时间:2009-12-16
我写的算法实现:
public class HelixAlgo {
  
  public void print(int len){
    if(len<=0){
      System.out.println("请输入大于0的整数!");
      return;
    }
    int[][] helix=calculate(len);
    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(int len){
    int[][] helix=new int[len][len];
    int min=0,max=len-1;//行列的最大最小值
    int row=0,col=0;
    for(int i=0;i<len*len;i++){
      helix[row][col]=i+1;
      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--;
      }
      if(row-1==min&&col==min){ //在一个周期结束时修改最大最小值
        min++;
        max--;
      }
    }
    return helix;
  }
  
  public static void main(String[] args){
    HelixAlgo algo=new HelixAlgo();
    algo.print(6);
  }
  
}




我在blog(http://shuishou119800.iteye.com/blog/549592)中对这个算法写了些分析,希望能一起探讨
发表时间:2009-12-16
Heis 写道
/**
 * @author Heis
 * @date Dec 11, 2009
 */
public class SnakeNum {

	
	public static void main(String[] args){
		int n=7;
		SnakeNum.print(SnakeNum.fill(n));		
	}
	/**
	 * 
	 * 算法复杂度为n
	 * 测试结果n=1000时,大概用时70ms
	 * 以下的算法,在for循环内的一些计算是不必要的,可以用变量保存,但是为了代码更加直观,就不做优化了。
	 * 
	 * @param n 矩阵边长
	 */
	public static int[][] fill(int n){
		Long startTime=System.currentTimeMillis();
		//第几圈
		int count=0;
		//转弯步数
		int step;
		//总圈数
		int all;
		//某圈开始累加的基数
		int startNum=0;
		//用于数组下标计算
		int startIndex;
		int k;
		int[][] array=null;
		if(n>0){
			array=new int[n][n];
		    all=n/2+n%2;
		    while(all>=count){
		    	step=n-1-(count<<1);
		    	count++;
		    			    	
		    	for(startIndex=count-1,k=1;k<step+1;k++){
		    		array[count-1][startIndex++]=startNum+k;	
		    	}
		    	
		    	for(startIndex=count-1,k=1;k<step+1;k++){
		    		array[startIndex++][n-count]=startNum+k+step;
		    	}
		    	
		    	for(startIndex=n-count,k=1;k<step+1;k++){
		    		array[n-count][startIndex--]=startNum+k+2*step;
		    	}
		    	
		    	for(startIndex=n-count,k=1;k<step+1;k++){
		    		array[startIndex--][count-1]=startNum+k+3*step;
		    	}
		    	startNum=4*step+startNum;
		    	
		    }
		    if(n%2>0){
		    	int mid=all-1;
		    	array[mid][mid]=n*n;
		    }
		}
		Long timeUsed=System.currentTimeMillis()-startTime;
		System.out.println("总用时:"+timeUsed+"ms");
		return array;		
	}
	
	/**
	 * 打印数组
	 * 
	 * @param array
	 */
	public static void print(int[][] array){
		if(array!=null){
			int n=array.length;
			int i=0,j;
			int count=Integer.valueOf(n*n).toString().length()+1;
			for(;i<n;i++){
				for(j=0;j<n;j++){
					System.out.printf("%"+count+"d",array[i][j]);
				}
				System.out.println();
			}
		}
	}
}

我把这个算法的分析写在博客上,有兴趣的可以去看看http://heis.iteye.com/blog/546981
Global site tag (gtag.js) - Google Analytics