二、矩阵遍历

  矩阵遍历是一个数据结构方面的问题。假设有一个矩阵Matrix,它共有RowCount行,每行有ColCount列,当利用y表示行数,x表示列数,那么利用Matrix[y,x]就可以访问矩阵中的任意元素。假设有一个10×10大小的矩阵,它的遍历方法有以下三种:

此主题相关图片如下:
(图1)

在上图中矩阵中的数字表示遍历到元素的先后次序,箭头表示遍历的方向。第一种的一般遍历法在很多编程书上都有介绍,而且经常作为循环代码的示范程序使用。这种遍历方法稍加修改就可以做到从右上角开始、从左下角开始、从右下角开始。这种遍历方法很简单,这里就不多说了。与一般遍历相反,螺旋遍历在所有的编程书和数据结构书上都没有讲到。现在详细的说明一下螺旋遍历。

  螺旋遍历可以做到以一个基点为中心向四周遍历,这个基点可以不是矩阵的中心点,实际上基点可以是矩阵上的任意一点,甚至可以是矩阵外的点。注意:这里所说的“点”是指可以用(y,x)访问的元素,当(y,x)坐标超出矩阵范围,例如(-1,-1),这就是矩阵外的点。可以看出螺旋遍历对于找图找色非常有用。螺旋遍历实现起来并不难,仔细观察图1中的螺旋遍历就会发现遍历可以由遍历方向和遍历步数组成。从(3,2)点开始向上遍历一步,再向右遍历一步,再向下遍历二步,再向左遍历二步,这时完成一轮,遍历方向又开始向上、向右、向下、向左一轮又一轮,同时遍历步数逐步加大。当向上遍历时y总是减1;当向右遍历时x总是加1;当向下遍历时y总是加1;当向左遍历时x总是减1,这样可以根据遍历方向计算出坐标的变化。另外螺旋遍历有可能会访问到矩阵外的点,在访问时要进行判断。正是由于螺旋遍历会访问矩阵外的点,遍历循环将无法停止从而出现死循环。这时要设定一个访问计数VisitCount,当遍历循环访问了矩阵中的所有点后退出循环。综上所述,螺旋遍历的示范代码如下:

type
    //遍历方向
    TAspect = (asLeft, asRight, asUp, asDown);

const
    //移动坐标差
    MoveVal : array [asLeft..asDown] of TPoint = (
        (X : -1; Y :  0), //asLeft
        (X :  1; Y :  0), //asRight
        (X :  0; Y : -1), //asUp
        (X :  0; Y :  1)  //asDown
    );

//矩阵大小
    RowCount = 10;
    ColCount = 10;

var
    //矩阵
    Matrix : array [0..RowCount-1,0..ColCount-1] of Integer;

//螺旋遍历(不支持步长)
procedure MatrixOrder1_(y,x : Integer);
var
    Aspect : TAspect;
    VisitCount,Count,i : Integer;
begin
    VisitCount:=0;
    Aspect:=asUp;
    Count:=1;
    while VisitCount<(RowCount*ColCount) do
    begin
        for i:=0 to Count-1 do
        begin
            if (x>=0) and (x<ColCount) and
               (y>=0) and (y<RowCount) then
            begin

//访问矩阵元素
                Matrix[y,x]:=VisitCount;

VisitCount:=VisitCount+1;
            end;
            x:=x+MoveVal[Aspect].X;
            y:=y+MoveVal[Aspect].Y;
        end;
        case Aspect of
            asLeft  : begin Aspect:=asUp;   Count:=Count+1; end;
            asRight : begin Aspect:=asDown; Count:=Count+1; end;
            asUp    : begin Aspect:=asRight; end;
            asDown  : begin Aspect:=asLeft;  end;
        end;
    end;
end;

  这里还有一个步长的问题,所谓步长就是指在遍历的时候跳过一些点,只平均访问矩阵中的某些点。例如以下数据就是步长为2以(3,2)为基点的螺旋遍历后的矩阵,其中“-”表示遍历时没有访问到的点。

输出矩阵:
   +  0  1  2  3  4  5  6  7  8  9
 0 :  -  -  -  -  -  -  -  -  -  -
 1 :  8  -  1  -  2  -  9  - 16  -
 2 :  -  -  -  -  -  -  -  -  -  -
 3 :  7  -  0  -  3  - 10  - 17  -
 4 :  -  -  -  -  -  -  -  -  -  -
 5 :  6  -  5  -  4  - 11  - 18  -
 6 :  -  -  -  -  -  -  -  -  -  -
 7 : 15  - 14  - 13  - 12  - 19  -
 8 :  -  -  -  -  -  -  -  -  -  -
 9 : 24  - 23  - 22  - 21  - 20  -

  使用步长可以实现矩阵的抽样查找,但上面给出的螺旋遍历算法却不支持步长。因为它要利用访问计数退出循环,使用步长时会使矩阵中访问到的点的数目不确定,使的上述算法出现死循环。对上述算法的一个改进是使用一个逻辑变量记录遍历一轮是否有访问到点。如果没有,说明这一轮访问已经以位于矩阵之外可以退出循环。当步长为1时这种改进的算法要比前面的算法更慢,因为它要“空转”一轮。而且这种算法也不支持矩阵外的点作为基点,它会使循环提前退出。支持步长的螺旋遍历算法的示范代码如下:注意这时的VisitCount仅作为测试使用,不作为退出循环的条件。

type
    //遍历方向
    TAspect = (asLeft, asRight, asUp, asDown);

const
    //遍历步长
    Interval = 2;

//移动坐标差
    MoveVal : array [asLeft..asDown] of TPoint = (
        (X : -Interval; Y : 0), //asLeft
        (X :  Interval; Y : 0), //asRight
        (X : 0; Y : -Interval), //asUp
        (X : 0; Y :  Interval)  //asDown
    );

//矩阵大小
    RowCount = 10;
    ColCount = 10;

var
    //矩阵
    Matrix : array [0..RowCount-1,0..ColCount-1] of Integer;

//螺旋遍历2(支持步长)
procedure MatrixOrder2(y,x : Integer);
var
    Aspect : TAspect;
    VisitCount : Integer; //访问计数,测试用
    Count,i : Integer;
    Visit : Boolean;
begin
    VisitCount:=0; //访问计数,测试用
    Visit:=false;
    Aspect:=asUp;
    Count:=1;
    while true do
    begin
        for i:=0 to Count-1 do
        begin
            if (x>=0) and (x<ColCount) and
               (y>=0) and (y<RowCount) then
            begin

//访问矩阵元素
                Matrix[y,x]:=VisitCount;
                VisitCount:=VisitCount+1; //访问计数,测试用

Visit:=true;
            end;
            x:=x+MoveVal[Aspect].X;
            y:=y+MoveVal[Aspect].Y;
        end;
        case Aspect of
            asLeft : begin
                if not Visit then break;
                Visit:=false;
                Aspect:=asUp;
                Count:=Count+1;
            end;
            asRight : begin Aspect:=asDown; Count:=Count+1; end;
            asUp    : begin Aspect:=asRight; end;
            asDown  : begin Aspect:=asLeft;  end;
        end;
    end;
end;
 
  对于回形遍历与螺旋遍历大同小异,这里就不多说了。在下面的压缩包中是矩阵遍历的示范程序,里面有一般遍历、螺旋遍历和回形遍历的示范代码,可以用于参考。

转载于:https://www.cnblogs.com/MaxWoods/archive/2013/06/14/3135360.html

Delphi下实现全屏快速找图找色 二、矩阵遍历相关推荐

  1. Delphi下实现全屏快速找图找色

    前言 最近有好几个朋友都在问我找图找色的问题,奇怪?于是乎写了一个专门用于找图找色的单元文件"BitmapData.pas".在这个单元文件中我实现了从文件中导入位图.屏幕截图.鼠 ...

  2. jquery,js实现手机端全屏轮播图手动滑动+自动切换(autoplay)

    jquery,js实现手机端全屏轮播图 使用了swiper插件,可手动滑动切换也可自动切换 效果图 css代码 只是作为参考,可以根据你自己的需求去改,这里我用的是上下两张背景图,图自行修改 html ...

  3. jquery导航图片全屏滚动、首页全屏轮播图,各式相册

    1.目录结构 源码 project css js image index1 index2 index3 index4 index.html index1到index4分为四个iframe标签引入的可单 ...

  4. 魔兽,极品飞车等等游戏在win7下不能全屏

    打开注册表编辑器:"开始"--"运行"--输入"regedit" 定位到HKEY_LOCAL_MACHINE------SYSTEM---- ...

  5. Windows7下游戏全屏问题通用解决方法

    一.Windows7下游戏全屏问题通用解决方法(推荐使用):Win键+R键,打开运行窗口,输入regedit 回车,这样就打开了注册表编辑器,然后,定位到以下位置:HKEY_LOCAL_MACHINE ...

  6. delphi编程 界面全屏代码(多种方法)

    delphi编程 界面全屏代码(多种方法) (2013-02-17 11:47:40) 转载▼ 标签: it 编程 分类: 编程相关 BorderStyle:=bsNone; SetBounds(0, ...

  7. 左右全屏banner焦点图 代码特效+苹果官网首页左右全屏banner焦点图效果+包括JS图片CSS样式等

    介绍 源码名称:[左右全屏banner焦点图]代码特效+苹果官网首页左右全屏banner焦点图效果+包括JS图片CSS样式等 源码大小:16.6KB 开发语言:PHP+Mysql 操作系统:Windo ...

  8. 从零学起之安卓篇《按键精灵安卓版找图找色应用汇总介绍》更新20

    本期主题:介绍目前手机按键(按键精灵安卓版)在编写脚本中,都需要用到哪些方式进行图色识别. 惯例先讲好处: 1.找色,如何计算颜色相似度,解决不同款式手机中画面颜色差异的问题. 2.找图,不太推荐,我 ...

  9. 苹果cmsV10添加全屏幻灯图、全屏轮播图教程

    使用全屏模板的小伙伴们很多都不会把首页的幻灯图片设置成全屏显示,今天就给大家讲解下幻灯图片全屏的设置教程. 1,设置全屏有2种途径:A是直接上传全屏的图片,B是通过苹果cms系统后台编辑视频的&quo ...

最新文章

  1. 行波和驻波动画演示gif_新技能get√ | 语文课上的笔顺动画可以这么做
  2. QT的QEasingCurve类的使用
  3. Vue — 第四天(components组件)
  4. 【C语言】利用递归函数求n的阶乘
  5. Greenplum 添加或删除standby master节点
  6. Scrapy爬去哪儿~上海一日游门票并存入MongoDB数据库
  7. java代码求IP和mac地址
  8. 1002 写出这个数 (20 分)—PAT (Basic Level) Practice (中文)
  9. oracle日期时间
  10. 动易CMS2006安装与配置
  11. 月租最便宜的手机卡_给大家推荐几张0月租,打电话还便宜的手机卡
  12. python爬取拉钩网信息
  13. 汽车控制器CAN通信DBC文件工具:EXCEL生成DBC和生成代码
  14. 数据库中索引原理及填充因子
  15. 微信表情符号已写入判决书
  16. 论文笔记:MICCAI2018 Cell Detection with Star-convex Polygons
  17. 大数据中心显示大屏幕用液晶拼接屏还是led显示屏?
  18. 西南科技大学计算机综合大纲,西南科技大学(专业学位)计算机技术研究生考试科目和考研参考书目...
  19. 6g运行和8g运行有什么差别
  20. Django 4.0文档学习(一)

热门文章

  1. dism++封装系统使用教程_客栈管理系统“订单来了”客房订单盒子使用教程
  2. MacOS安装zsh插件zsh-autosuggestion(自动命令补全和建议)
  3. Windows 系统下使用 putty 客户端通过 SSH 远程连接 AWS 服务器
  4. MyEclipse for Mac快捷键
  5. python cookie使用_Python使用cookielib模块操作cookie的实例教程
  6. Numpy的切片操作
  7. centos 7 mysql随机密码_在centos中安装了mysql5.7之后解决不知道随机的密码的问题...
  8. C语言:--位域和内存对齐
  9. 为什么jupyterlab运行程序的时候会自动停止_气象人的JupyterLab
  10. centos7 mysql启动后端口_centos7 修改mysql5.7默认端口后启动异常