19,468
社区成员
发帖
与我相关
我的任务
分享
BOOL VXIntersect( DWORD32* pVXRanges, ULONG ulCnt ) // 交运算
{
DWORD32 dwMin = 0;
DWORD32 dwMax;
DWORD32 dwOldMin;
BOOL bFind;
if (0 != ulCnt % 2 || 0 == ulCnt) // 不是2的倍数肯定是一个错误的范围数组, 不能够进行交运算
return FALSE;
ULONG i = 0;
m_pVXCursor = m_pVXHead;
do
{
dwMax = pVXRanges[i] - 1;
bFind = FALSE;
while (NULL != m_pVXCursor)
{
if (m_pVXCursor->dwVXMin > dwMin) // 查找不到对应段
break;
if (dwMin >= m_pVXCursor->dwVXMin && m_pVXCursor->dwVXMax >= dwMin) // 查找到对应段
{
bFind = TRUE;
break;
}
m_pVXCursor = m_pVXCursor->pVXNext;
}
if (TRUE == bFind && dwMax <= m_pVXCursor->dwVXMax) // 小端查找到, 并且大端也在本范围段内时
{
if (dwMin == m_pVXCursor->dwVXMin && dwMax == m_pVXCursor->dwVXMax) // 刚好复盖整个范围, 当前段删除即可
VXDelete();
else if (dwMin == m_pVXCursor->dwVXMin) // 小段刚好全部合并, 大段写进去即可
{
m_pVXCursor->dwVXMin = dwMax + 1;
//m_pVXCursor = m_pVXCursor->pVXNext;
}
else if (dwMax == m_pVXCursor->dwVXMax) // 大段刚好全部合并, 留下小段即可
{
m_pVXCursor->dwVXMax = dwMin - 1;
m_pVXCursor = m_pVXCursor->pVXNext;
}
else // 不能够闭合, 要创建新的段
{
dwOldMin = m_pVXCursor->dwVXMin;
m_pVXCursor->dwVXMin = dwMax + 1;
VXInsertBefore( dwOldMin, dwMin - 1 );
}
}
else
{
if (TRUE == bFind)
{
if (m_pVXCursor->dwVXMin == dwMin) // 刚好合并时, 删除当前段即可
VXDelete();
else // 不能够闭合, 把当前段的最大值修改即可
{
if (0 == dwMin)
{
printf("error! impossible be zeor of min here!");
system("pause");
}
m_pVXCursor->dwVXMax = dwMin - 1;
m_pVXCursor = m_pVXCursor->pVXNext;
}
}
while (NULL != m_pVXCursor)
{
if (m_pVXCursor->dwVXMax <= dwMax) // 只要小于大端, 就可以直接删除
{
VXDelete();
continue;
}
if (m_pVXCursor->dwVXMin > dwMax) // 当前块的小端比当前比较的大端还大, 代表不需要再继续处理了
break;
if (m_pVXCursor->dwVXMax >= dwMax)
{
if (m_pVXCursor->dwVXMax == dwMax) // 刚好闭合, 删除这个块
VXDelete();
else // 不能闭合, 修改最小值
{
m_pVXCursor->dwVXMin = dwMax + 1;
//m_pVXCursor = m_pVXCursor->pVXNext;
}
break;
}
m_pVXCursor = m_pVXCursor->pVXNext;
}
}
i ++;
dwMin = pVXRanges[i] + 1;
i ++;
}while (i < ulCnt);
if (0 != dwMin)
{
if (NULL == m_pVXCursor)
m_pVXCursor = &m_VXEnd;
while (NULL != m_pVXCursor)
{
if (m_pVXCursor->dwVXMin > dwMin) // 查找不到对应段
break;
if (dwMin >= m_pVXCursor->dwVXMin && m_pVXCursor->dwVXMax >= dwMin) // 查找到对应段
{
if (dwMin == m_pVXCursor->dwVXMin && dwMin == m_pVXCursor->dwVXMax) // 刚好复盖整个范围, 当前段删除即可
VXDelete();
else if (dwMin == m_pVXCursor->dwVXMin) // 实现插入单个区间, 刚好为边界就直接加即可
m_pVXCursor->dwVXMin = dwMin + 1;
else if (dwMin == m_pVXCursor->dwVXMax) // 大段刚好全部合并, 留下小段即可
m_pVXCursor->dwVXMax = dwMin - 1;
else // 非边界时要创建一个新的区域
{
dwOldMin = m_pVXCursor->dwVXMin;
m_pVXCursor->dwVXMin = dwMin + 1;
VXInsertBefore( dwOldMin, dwMin - 1 );
}
break;
}
m_pVXCursor = m_pVXCursor->pVXNext;
}
}
m_pVXCursor = m_pVXHead;
return TRUE;
}
整个过程就是归纳为:
先用小端查找
查找到时
当前段为起点
判大端是否也在本段内
在本段内
小端跟小端合并, 大端跟大端合并, 即插入一个新段(假如刚好为边界值是不用分段)
不在本段内
本段的大端变成当前查找的小端作为大端.
用大端查找位置, 所经过的段假如大端比当前查找的大端要小, 直接删除
查找不到, 删除完毕即可.
查找得到, 根据是否刚好为边界来进行决定分段还是不分段.
查找不时
当前段为起点
用大端查找后段, 所经过的段假如大端比当前查找的大端要小, 直接删除
查找不到, 删除完毕即可
查找得到, 根据是否刚好为边界来进行决定分段还是不分段.
即查找到跟查找不到时, 是小了一个在本段内进行比较的过程.
BOOL VXIntersect( DWORD32* pVXRanges, ULONG ulCnt ) // 交运算
{
DWORD32 dwMin = 0;
DWORD32 dwMax;
DWORD32 dwOldMin;
BOOL bFind;
if (0 != ulCnt % 2 || 0 == ulCnt) // 不是2的倍数肯定是一个错误的范围数组, 不能够进行交运算
return FALSE;
ULONG i = 0;
m_pVXCursor = m_pVXHead;
do
{
dwMax = pVXRanges[i] - 1;
bFind = FALSE;
while (NULL != m_pVXCursor)
{
if (m_pVXCursor->dwVXMin > dwMin) // 查找不到对应段
break;
if (dwMin >= m_pVXCursor->dwVXMin && m_pVXCursor->dwVXMax >= dwMin) // 查找到对应段
{
bFind = TRUE;
break;
}
m_pVXCursor = m_pVXCursor->pVXNext;
}
if (TRUE == bFind && dwMax <= m_pVXCursor->dwVXMax) // 小端查找到, 并且大端也在本范围段内时
{
if (dwMin == m_pVXCursor->dwVXMin && dwMax == m_pVXCursor->dwVXMax) // 刚好复盖整个范围, 当前段删除即可
VXDelete();
else if (dwMin == m_pVXCursor->dwVXMin) // 小段刚好全部合并, 大段写进去即可
{
m_pVXCursor->dwVXMin = dwMax;
m_pVXCursor = m_pVXCursor->pVXNext;
}
else if (dwMax == m_pVXCursor->dwVXMax) // 大段刚好全部合并, 留下小段即可
{
m_pVXCursor->dwVXMax = dwMin;
m_pVXCursor = m_pVXCursor->pVXNext;
}
else // 不能够闭合, 要创建新的段
{
dwOldMin = m_pVXCursor->dwVXMin;
m_pVXCursor->dwVXMin = dwMax;
VXInsertBefore( dwOldMin, dwMin );
}
}
else
{
if (TRUE == bFind)
{
if (m_pVXCursor->dwVXMin == dwMin) // 刚好合并时, 删除当前段即可
VXDelete();
else // 不能够闭合, 把当前段的最大值修改即可
{
if (0 == dwMin)
{
printf("error! impossible be zeor of min here!");
system("pause");
}
m_pVXCursor->dwVXMax = dwMin - 1;
}
}
while (NULL != m_pVXCursor)
{
if (m_pVXCursor->dwVXMax < dwMax) // 只要小于大端, 就可以直接删除
{
VXDelete();
continue;
}
if (m_pVXCursor->dwVXMin > dwMax) // 当前块的小端比当前比较的大端还大, 代表不需要再继续处理了
break;
if (m_pVXCursor->dwVXMax >= dwMax)
{
if (m_pVXCursor->dwVXMax == dwMax) // 刚好闭合, 删除这个块
VXDelete();
else // 不能闭合, 修改最小值
m_pVXCursor->dwVXMin = dwMax + 1;
break;
}
m_pVXCursor = m_pVXCursor->pVXNext;
}
}
i ++;
dwMin = pVXRanges[i] + 1;
i ++;
}while (i < ulCnt);
if (0 != dwMin)
{
if (NULL == m_pVXCursor)
m_pVXCursor = &m_VXEnd;
if (dwMin == m_pVXCursor->dwVXMin) // 实现插入单个区间, 刚好为边界就直接加即可
m_pVXCursor->dwVXMin = dwMin + 1;
else // 非边界时要创建一个新的区域
{
dwOldMin = m_pVXCursor->dwVXMin;
m_pVXCursor->dwVXMin = dwMin + 1;
VXInsertBefore( dwOldMin, dwMin - 1 );
}
}
m_pVXCursor = m_pVXHead;
}
void GetIntersect(CArray<INTPARE,INTPARE> &TableA,CArray<INTPARE,INTPARE> &TableB,CArray<INTPARE,INTPARE> &TableRes)
{
TableRes.RemoveAll();
INTPARE PareA,PareB;
int a,b,c,d,nStartPoint=0;
for (int i=0;i<TableA.GetCount();i++)
{
PareA=TableA[i];
for (int j=nStartPoint;j<TableB.GetCount();j++)
{
PareB=TableB[j];
if(PareA.b<PareB.a)
{
break;
}
a=PareA.a-PareB.a;
b=PareA.a-PareB.b;
c=PareA.b-PareB.a;
d=PareA.b-PareB.b;
if(a==0 || b==0 || c==0 || d==0 || (a^b)>>31 || (b^c)>>31 || (c^d)>>31)//有交叉
{
INTPARE pare;
pare.a=max(PareA.a,PareB.a);
pare.b=min(PareA.b,PareB.b);
TableRes.Add(pare);
nStartPoint=j;
}
}
}
}
a+=abs(a);
b+=abs(b);
c+=abs(c);
d+=abs(d);
if(a==0 || b==0 || c==0 || d==0)//有交叉
{
INTPARE pare;
pare.a=max(PareA.a,PareB.a);
pare.b=min(PareA.b,PareB.b);
TableRes.Add(pare);
}
typedef struct
{
int a,b;
}INTPARE;
void GetIntersect(CArray<INTPARE,INTPARE> &TableA,CArray<INTPARE,INTPARE> &TableB,CArray<INTPARE,INTPARE> &TableRes)
{
TableRes.RemoveAll();
INTPARE PareA,PareB;
int a,b,c,d;
for (int i=0;i<TableA.GetCount();i++)
{
PareA=TableA[i];
for (int j=0;j<TableB.GetCount();j++)
{
PareB=TableB[j];
a=PareA.a-PareB.a;
b=PareA.a-PareB.b;
c=PareA.b-PareB.a;
d=PareA.b-PareB.b;
if(a!=0) a/=abs(a);
if(b!=0) b/=abs(b);
if(c!=0) c/=abs(c);
if(d!=0) d/=abs(d);
if(a*b<=0 || b*c<=0 || c*d<=0)//有交叉
{
INTPARE pare;
pare.a=max(PareA.a,PareB.a);
pare.b=min(PareA.b,PareB.b);
TableRes.Add(pare);
}
}
}
};