打印本文 打印本文 关闭窗口 关闭窗口
算法问题 用SQL写出当M*N时的螺旋矩阵算法
作者:武汉SEO闵涛  文章来源:敏韬网  点击数6748  更新时间:2007/11/14 13:12:51  文章录入:mintao  责任编辑:mintao
;  from (select level as i from dual connect by level <= 4) a,
 21                         (select level as j from dual connect by level <= 4) b))
 22   group by i
 23  /

      CO11       CO12       CO13       CO14
---------- ---------- ---------- ----------
         1          2          3          4
        12         13         14          5
        11         16         15          6
        10          9          8          7

----------------------------------------------------------------------------------------


以上两种旋转都是由外向内的, 如果有兴趣也可以做成由内想外的
不过如果大家还要把结果90度旋转, 在顺序固定的情况下, 应该就是行列转换的问题了
不过如果要做成圆形的, 我觉得不太可能了, 正n边形倒是可以考虑, 不过要看n的值是多大, 如果趋于正无穷, 那就是圆了, ^_^

对了,jacky,能大概说一下这个螺旋特征码的算法原理么?
--------------------------------------------------------------------------------


螺旋总要有个起点, 就用上面的那个结果来说明吧
起点是(1,1), 如果是顺时针的话, 旋转时依次走过的途径是 上->右->下->左->上->右->下->左..., 知道最后在螺旋中心结束, 但是可以注意到旋转是会越来越远离外边界
根据这个我们就可以获取螺旋特征码了
4*4的矩阵, 那么可以认为 i=1, j=1, i=4, j=4, 这就是这个螺旋的4个边界, 顺时针旋转时, 离边界越近, 那么顺序就越靠前, 当距离边界相同时, 边界的优先级就要根据 上右下左(起点为1,1, 顺时针旋转的边界优先级) 而定了, 如果这个也相同, 那么就要根据这个点离前一个边界的距离而定, 离的越近, 优先级越高, 根据以上规则, 可以得出特征码共有三位, 第一位代表距离边界的距离, 第二位代表距离哪个边界最近(我的sql中用1,2,3,4分别表示四个边界), 第三位代表距离前一个边界的距离(因为目的是为了排序, 计算时没有严格按照这个距离值进行表示^_^)
对应上面螺旋特征码的规则, 使用case least(...)判断离边界的距离和距离最近的边界是那个边界, when ... then后的取值再确定距离前一个边界的距离, 这样就完成了特征码, 剩下的就是对特征码排序和行列转换了, 这个就不用说了吧, 大家应该都会了, ^_^

也来学一下JACKYWOOD兄, 写一个SQL:

JACK的实现, 采用了行列转换把生成的序列做成二维表, 所以要求列数是固定的, 若要实现N的矩阵的算法, 行列转换正如其所言, 可以通过二个SQL实现.
现换一下思路, 用SYS_CONNECT_BY_PATH函数, 借用JACK的思路, 实现N的矩阵生成, 如下请各位指点:

代码:--------------------------------------------------------------------------------
SQL> var n number;
SQL> exec :n := 3;

PL/SQL 过程已成功完成。

SQL> select replace(max(sys_connect_by_path(rank, '''','''')), '''','''') str
  2     from (select i, j,
  3                 to_char(rank() over(order by tag), ''''9999'''') as rank
  4            from (select i,
  5                         j,
  6                   -- 逆时针螺旋特征码 counter-clockwise
  7                         case least(j - 1, :n - i, :n - j, i - 1)
  8                         when j - 1 then
  9                            (j - 1) || ''''1'''' || i
 10                         when :n - i then
 11                            (:n - i) || ''''2'''' || j
 12                         when :n - j then
 13                            (:n - j) || ''''3'''' || (:n - i)
 14                         when i - 1 then
 15                            (i - 1) || ''''4'''' || (:n - j)
 16                         end as tag
 17                    from (select level as i from dual connect by level <= :n) a,
 18                         (select level as j from dual connect by level <= :n) b
 19                 )
 20          )
 21     start with j = 1
 22     connect by j - 1 = prior j and i = prior i
 23     group by i
 24     order by i;

STR
-------------------------------------------------------------------------------------------------
    1    8    7
    2    9    6
    3    4    5

SQL> exec :n := 4;

PL/SQL 过程已成功完成。

SQL> /

STR
-------------------------------------------------------------------------------------------------
    1   12   11   10
    2   13   16    9
    3   14   15    8
    4    5    6    7

SQL> exec :n := 5;

PL/SQL 过程已成功完成。

SQL> /

STR

上一页  [1] [2] [3] [4] [5] [6]  下一页

打印本文 打印本文 关闭窗口 关闭窗口