// 区域分块
// VC 2008
#include "stdafx.h"
#include <list>
#include <iostream>
#include <assert.h>
using namespace std;
class Area
{
public:
Area(WORD iSizeX, WORD iSizeY, BYTE iSpace, BYTE iFree)
: wSizeX(iSizeX), wSizeY(iSizeY), bySpace(iSpace), byFree(iFree)
{ ; }
~Area() { ; };
// 区域编号
DWORD AreaNumber(BYTE* pData);
private:
// 添加邻居
DWORD PushNear(std::list<int>& vBlock, DWORD dwPos, BYTE* pData);
private:
const WORD wSizeX;
const WORD wSizeY;
const BYTE bySpace;
const BYTE byFree;
};
int _tmain(int argc, _TCHAR* argv[])
{
const int iX = 5;
const int iY = 4;
BYTE byData[iY][iX] =
{
1,1,1,1,1,
0,0,0,1,0,
1,1,0,0,1,
1,0,1,1,1,
};
Area a(4, 4, 0, 1);
int x = a.AreaNumber(&byData[0][0]);
// 显示结果
for(int y=0; y<iY; y++)
{
cout << "/n";
for(int x=0; x <iX; x++)
{
cout << int(byData[y][x]);
}
}
return 0;
}
// 区域编号
// 0 表示隔断
// 1 表示尚未分区域
// 大于1表示区域编号
DWORD Area::AreaNumber(BYTE* pData)
{
// 初始化
std::list<BYTE> vBlockPos;
for(int i=0; i< wSizeX * wSizeY; i++)
{
if(pData[i] != bySpace)
{
vBlockPos.push_back(i);
}
}
// 分块
int iMaxBlock = byFree; // 准备用的块号
while(!vBlockPos.empty())
{
// 找第一个没有分块的区域
int iPos = vBlockPos.front();
vBlockPos.pop_front( );
if(pData[iPos] != byFree)
{
// 不是未处理的
continue;
}
// 新块
iMaxBlock++;
if(iMaxBlock >= BYTE(-1))
{
// 错误, 块数太多
return 0;
}
// 处理当前块
std::list<int> vCurBlock;
vCurBlock.push_back(iPos);
while(!vCurBlock.empty())
{
int iPos2 = vCurBlock.front();
vCurBlock.pop_front( );
if(pData[iPos2] != byFree)
{
// 不是未处理的
continue;
}
if(pData[iPos2] == 0)
{
// 边界区域
continue;
}
// 处理
pData[iPos2] = iMaxBlock;
// 将相邻的加入待处理列表
PushNear(vCurBlock, iPos2, pData);
}
}
return iMaxBlock;
}
// 添加邻居
// 这里处理4个相邻
DWORD Area::PushNear(std::list<int>& vBlock, DWORD dwPos, BYTE* pData)
{
DWORD iAdd = 0;
if(dwPos >= wSizeX)
{
int iPosUp = dwPos - wSizeX;
if(pData[iPosUp] == byFree)
{
vBlock.push_back(iPosUp);
iAdd++;
}
}
if(dwPos + wSizeX < wSizeX * wSizeY)
{
int iPosDown = dwPos + wSizeX;
if(pData[iPosDown] == byFree)
{
vBlock.push_back(iPosDown);
iAdd++;
}
}
if(dwPos % wSizeX >= 1)
{
int iPosLeft = dwPos - 1;
if(pData[iPosLeft] == byFree)
{
vBlock.push_back(iPosLeft);
iAdd++;
}
}
if(dwPos % wSizeX < wSizeX - 1)
{
int iPosRight = dwPos + 1;
if(pData[iPosRight] == byFree)
{
vBlock.push_back(iPosRight);
iAdd++;
}
}
return iAdd;
}
/*
运行结果:
22222
00020
33004
30444
*/
625

被折叠的 条评论
为什么被折叠?



