颜色替换的递归算法

假设以二维数组g[1..m][1..n]表示一个图像区域,g[i][j]表示该区域中点(i,j)所具颜色,其值为从0到k的整数。试编写递归算法,将点(i0,j0)所在区域的颜色置换为颜色c。约定与(i0,j0)同色的上、下、左、右的邻接点为同色区域的点。

表示图像区域的类型定义如下:

/* 在g[1..m][1..n]中,将元素g[i0][j0] */

/* 所在的同色区域的颜色置换为颜色c */

typedef char GTYPE[m+1][n+1];

 1     voidChangeColor(GTYPE g,int m,int n,char c,int i0,int j0)
 2     {
 3         char temp;
 4
 5         //判断是否在合法区域内
 6         if(i0 <1|| i0 > m || j0 <1|| j0 > n)
 7             return;
 8
 9         //防止进入死递归
10         temp = g[i0][j0];
11         if(c == temp)
12             return;
13
14           g[i0][j0]= c;
15           //依次判断上、下、左、右点
16         if(i0 -1>=1&& g[i0-1][j0]== temp)
17             ChangeColor(g,m,n,c,i0-1,j0);
18         if(i0 +1<= m && g[i0+1][j0]== temp)
19             ChangeColor(g,m,n,c,i0+1,j0);
20         if(j0 -1>=1&& g[i0][j0-1]== temp)
21             ChangeColor(g,m,n,c,i0,j0-1);
22         if(j0+1<= n && g[i0][j0+1]== temp)
23             ChangeColor(g,m,n,c,i0,j0+1);
24     }

思路:总体思路是先替换再查找。从指定的点开始,先保存该点的颜色值temp再替换成c颜色值;然后再分别判断区域内上下左右的颜色值是否等于temp,如果等于,则利用相同的方法,递归地判断下一个点;直到所有符合要求的点被替换成c颜色值为止。

有些读者会提出:可不可以把替换颜色值的操作放在其中一个if语句之后,也就是让函数先查找下一个点,再替换指定点的颜色值?

我们假设将替换颜色值的语句放在最后一个if之后(其他情况类似),代码如下

 1     voidChangeColor(GTYPE g,int m,int n,char c,int i0,int j0)
 2     {
 3         char temp;
 4
 5         //判断是否在合法区域内
 6         if(i0 <1|| i0 > m || j0 <1|| j0 > n)
 7             return;
 8
 9         //防止进入死递归
10         temp = g[i0][j0];
11         if(c == temp)
12             return;
13
14         //依次判断上、下、左、右点
15         if(i0 -1>=1&& g[i0-1][j0]== temp)
16             ChangeColor(g,m,n,c,i0-1,j0);
17         if(i0 +1<= m && g[i0+1][j0]== temp)
18             ChangeColor(g,m,n,c,i0+1,j0);
19         if(j0 -1>=1&& g[i0][j0-1]== temp)
20             ChangeColor(g,m,n,c,i0,j0-1);
21         if(j0+1<= n && g[i0][j0+1]== temp)
22             ChangeColor(g,m,n,c,i0,j0+1);
23
24         g[i0][j0]= c;
25     }

我们知道函数每调用一次都会将函数实参、函数里的局部变量都压栈保存,所以当你调用ChangeColor函数时都会在栈中保存g(二维函数指针,占4个字节)、数组范围m和n、替换的颜色值c、指定点坐标i0和j0以及函数里的局部变量temp;而且每个函数栈在一般情况下都是独立、互不影响的,这样才能保证函数的正常运行。

当我们调用ChangeColor(g,6,4,2,4,3)想要将(4,3)点同色区域替换成颜色值2时,此时会将函数的实参和局部变量temp压栈,我们简单用(4,3)表示。根据函数代码,会先查找指定点的上面的点(3,3),因为(3,3)颜色值为1,将(3,3)压栈,继续在(3,3)指定点的基础上查找上面的点,此时该点颜色值为0不符合;接下来指定点(3,3)会继续查找下面的点,此时由于(4,3)的颜色值为1,还没被替换为颜色值2,符合替换要求,将(4,3)压栈,那么问题来了,兜了一圈又回到了原来的点,这样便会无限地递归下去。因为栈的空间是有限的,每次函数调用都会压栈,从而出现栈溢出。

当一个点跳到另一个点之前没被替换,而跳回来时也没改变便会进入死递归中,直到栈溢出发生错误,所以需要在所有跳转之前,执行颜色值替换操作。

细心的读者可能会问:如果替换的颜色值c和开始指定点的颜色一样,那会发生什么?

毫无疑问是死递归最后栈溢出。上面已经说过为了防止“一个点跳到另一个点之前没被替换,而跳回来时也没改变”这种情况,需要在所有跳转之前,执行颜色值替换操作。但是此时替换的颜色值和指定点的颜色值一样,那根本和没替换没什么区别,当一个点跳到另一个点后,之后也一定会跳回来,从而进入特殊的死递归。

最后通过以上一个简单的递归例子总结一句话:语言再高级,算法不严谨也没用!

延伸阅读:http://www.nowamagic.net/librarys/veda/detail/2314

本文链接:http://www.cnblogs.com/cposture/p/4487417.html

时间: 2024-08-01 19:45:45

颜色替换的递归算法的相关文章

第十课 切片工具 修复画笔工具 修补工具 颜色替换工具

切片工具.切片选取工具K 切片工具:用来划分图像的区域 切片选取工具:可以用来选中所划分的切片,并且移动或者删除等. 将图像格式存为网页Ctrl+Alt+Shift+S,再次打开时可以看到所划分的裁切区域. 修复画笔工具:J 修补工具:J 颜色替换工具:J 修复画笔工具的用法:按住Alt键不放,在需要复制的地方单击即可进行取样,再需要放置的地方进行涂抹即可,涂抹时十字光标的走向决定涂抹被覆盖的对象/复制得来的对象会受当前层颜色的影响,若在属性栏中将正常模式改为“替换”则不会受影响./若不勾选“对

9-3修复画笔/修补/污点修复画笔/颜色替换/红眼移除工具

http://www.missyuan.com/thread-350814-1-1.html 修复画笔工具[J/SHIFT J] 图章工具只负责将一定数量的人口迁移过来,迁移完就了事.而修复画笔工具不仅迁移人口,还将其渗透到当地的生活氛围中,使新移民看上去不那么不合群 修补工具,修补工具的作用原理和效果与修复画笔工具是完全一样的,只是它们的使用方法有所区别.修补工具的操作是基于区域的,因此要先那样定义好一个区域(与选区类似) 那么公共栏中的修补选项改为目标的话,会有什么区别呢?首先我们来明确一下

关于影像颜色替换

超图软件日前正式公布SuperMap iObjectsJava/.NET 8C SP1版本号.新版本号依据用户的特殊须要.对影像颜色值替换功能进行优化和扩展.支持很多其它的影像颜色值替换形式. 一.影像颜色透明处理 如图 1所看到的,地图中加入了几幅影像,每幅影像都有黑色的边,因为影像未进行拼接,所以在显示时相互叠合的部分被黑色边所影响,此时要比較好地显示影像叠合的部分就须要将黑色边缘去掉,因为这里仅是浏览一下影像效果,而不想花时间做影像拼接,所以我们能够通过影像图层提供的"透明色"功

网站多种主题颜色替换的不同实现

一般来说网站改版或者由于用户喜好不同,需要准备几套不同的主题or皮肤, 本文从颜色示例,记录一下就网站主要配色切换的几种方法及场景: 一 ,每一套主题配置一份资源文件(web/css). 这种思路是最简单的,在布局文件中引用选中主题的资源即可, 缺点在于 需要生成几份文件并维护,网站本身引用插件的资源文件也需要配置成对应几份,具体实现就不多说了 二,使用CSS变量来配置主题,方法如下: 1,根据管理员选择生成主题css颜色文件, $colorcss=":root{".PHP_EOL .

PS图片中字体或图像的颜色替换

第一步.打开替换颜色修改框.步骤:图像--调整--替换颜色 第二部.选择要替换的颜色 完后点确定,就可以修改好自己想要的颜色.

pyqt界面颜色替换学习(pyqt精彩实例处学习)

# -*- coding: utf-8 -*- from PyQt4.QtGui import * from PyQt4.QtCore import * import sys QTextCodec.setCodecForTr(QTextCodec.codecForName("utf8")) class Palette(QDialog): def __init__(self,parent=None): super(Palette,self).__init__(parent) self.s

[VBA]批量替换PPT里的字体颜色

不知道为什么计组老师的大量课件字体是伤害视力的亮蓝色……看久了眼睛疼,想把颜色替换成保护视力一点的灰色,但是找了N久也没找到在图形界面上直接操作的方法,于是在MSDN上晃了晃,Google了一下,写了个VBA小脚本,只替换选定颜色,这样可以保留红色或者其他颜色的高亮,顺便把让人分心的花花背景也干掉. Sub ReplaceColor() Dim shape As shape Dim slide As slide Dim txt As TextRange On Error Resume Next

利用色光三原色调整图片颜色

最近学习了android中的图片颜色的处理,现在来总结一下.android中存在三种方式来调整图片的颜色,来达到不同的效果.分别是:利用色光三原色来调整图片颜色,利用颜色矩阵来调整图片颜色,利用调整每一个像素点来调整图片颜色.显然调整颜色的方式是越来越细致的.那么在这一篇文章中,就总结一下通过色光三原色来调整图片的颜色. 一.基础知识 首先说一下基础的颜色知识.android中采取的颜色模型是RGBA模型.即R代表红色,G代表绿色,B代表蓝色,A代表透明度.而通过改变一张图片的三原色的色相,饱和

Quartz2D 编程指南(一)概览、图形上下文、路径、颜色与颜色空间

概览 图形上下文 路径 颜色与颜色空间 变换 图案 阴影 渐变 透明层 Quartz 2D 中的数据管理 位图与图像遮罩 CoreGraphics 绘制 Layer 0.说明 本篇博客主要是对官方文档的总结与补充.翻译部分参考了南峰子的博客.你可以在参考资料中查看. 1.概览 简介 Quartz2D 是二维图形绘制引擎,支持 iOS 和 OS X. Page Quartz2D 在图像中使用了绘画者模型.在绘画者模型中,每个连续的绘制操作都是将一个绘制层放置于一个画布,我们通常称这个画布为 Pag