RockCarry 兄我想到一个办法,不过还是要开辟额外的内存来标记哪些点已经被放置成功,
他要额外消耗的内存,比如你的图片 高 H, 宽 W
那么额外需要开辟 H*W /8 个字节。
2000x2000 / 8 = 500000 字节;换算成 M才0.4M多
所以我想也许可以满足你的要求
我们首先还是以你上面给出的例子进行说明:
a b c d
e f g h
i j k l
int w = 4;
int h = 3;
BYTE pdata[] = { a, b, c, d, e, f, g, h, i, j, k, l };
那么我们对待他的的时候,可以把 pdata[]数组看成是2维的,在提取数据的时候,自己转化就是了。
那么我们来看看他转化后的情况,来找出规律
i e a
j f b
k g c
l h d
int w = 3;
int h = 4;
BYTE pdata[] = { i, e, a, j, f, b, k, g, c, l, h, d };
这样我们得出的规律表是
a: (0,0) -> (2,0)
b: (1,0) -> (2,1)
c: (2,0) -> (2,2)
d: (3,0) -> (2,3)
e: (0,1) -> (1,0)
f: (1,1) -> (1,1)
g: (2,1) -> (1,2)
h: (3,1) -> (1,3)
i: (0,2) -> (0,0)
j: (1,2) -> (0,1)
l: (2,2) -> (0,2)
k: (3,2) -> (0,3)
他的规律很显而易见,就是 原来的 X变Y, 原来的Y由W-1-Y得到新的X。
然后我们建立一个标记表 ,W*H/8;在这里就是 3*4/8 = 1...4 也就需要两个字节来标记每个点的置换情况。
为了发表表达,我们把这个表也建立成2维的与原图对应,(当然在使用中应该开辟一个连续数组只是在用的时候在2维坐标和1维坐标之间相互转化就是了,当然这里是位操作)
标记表:(标记的2维坐标应该是转换后的情况,而且当然是以位来标记的)
0 0 0
0 0 0
0 0 0
0 0 0
好,我们来看整个是怎么云做的。
1. 首先看第一个元素 a (0,0) -> (2.0)
先查看 标记表的(2,0)位置,为0,说明没被置换。先记录,c元素原始位置 (2.0)那将a,c元素互换并操作标记表。这之后情况是
置换表
c b a d
e f g h
i j k l
标记表
0 0 1
0 0 0
0 0 0
0 0 0
2.查看C本来应该在的位置是否和现在相符,原本 c: (2,0) -> (2,2),而现在c在(0,0)
那么重复上面1过程,他与现在(2,2)处的k元素,互换,并记录下k元素的原始位置,这样后的结果是
置换表
k b a d
e f g h
i j c l
标记表
0 0 1
0 0 0
0 0 1
0 0 0
3.经过上面的步骤,最后将形成小范围的互换成功。就按上面继续,k将与i互换,而i将恰好被换到他本该到的(0,0)处。这样后一个小范围循环结束,最后的结果
置换表
i b a d
e f g h
k j c l
标记表
1 0 1
0 0 0
1 0 1
0 0 0
4.而后,我们将进行第二个元素,b的呼唤,经过一个循环过程,又将是小范围互换成功
简要经过 b<->g g<->j j<->e 最终e将停在正确位置,结果
置换表
i e a d
j f b h
k g c l
标记表
1 1 1
1 0 1
1 1 1
0 0 0
5.然后进行现在第3个元素a,可一检查标记表,他已经置换OK拉,所以,接下来就是第4个元素d,在经过以上步骤就可以实现全部的元素置换成功。
这个算法介绍完毕,现在补充一句 额外开辟的内存是 W*H/8 +2*int 因为要记录被置换元素的原始坐标。
我想这个算法应该可以满足RockCarry 兄的要求,只是在实现的过程中,要在优化优化,毕竟在嵌入试上跑要讲求效率
祝成功~!
[此贴子已经被作者于2007-8-8 23:18:40编辑过]