C# バイト配列比較/二分岐岐探査(バイナリサーチ)
// バイト配列比較
// nCompare
//
//
//
//
//
//
0 は等しい
0 より大きいは、bySrcXの方が大きい
0 より小さいは、bySrcXの方が小さい
0 より大きいは、bySrcXの方が大きい
0 より小さいは、bySrcXの方が小さい
// 戻り値
//
//
//
//
//
//
呼び出し成功 0
比較する要素がない -1
引数が不正 -2
比較する要素がない -1
引数が不正 -2
public static int Compare( out int nCompare, int nLength, byte bySrcX, int nOffsetX, byte bySrcY, int nOffsetY )
{
nCompare = 0;
if( nLength > bySrcX.Length - nOffsetX )
{
nLength = bySrcX.Length - nOffsetX;
}
if( nLength > bySrcY.Length - nOffsetY )
{
nLength = bySrcY.Length - nOffsetY;
}
if( nLength <= 0 )
{
if( nLength == 0 )
{
return -1;
}
return -2;
}
for( int i = 0; i < nLength; i ++ )
{
nCompare = (int)bySrcX[nOffsetX + i] - (int)bySrcY[nOffsetY + i];
if( nCompare != 0 )
{
return nCompare;
}
}
return 0;
}
// バイト配列 bySrc からバイト配列 byTarget を探す
// バイト配列 bySrc は nBlockLength サイズのブロックの集まりで、
// 昇順になっていること
public static int BinarySearch( byte bySrc, byte byTarget, int nBlockLength )
{
int nBlockNum = bySrc.Length / nBlockLength;
int nLow = 0;
int nHigh = nBlockNum - 1;
while( nLow < nHigh )
{
int nIndex = (nLow + nHigh) / 2;
int nResult = Compare( out nCompare, byTarget.Length, byTarget, 0, bySrc, nBlockLength * nIndex );
if( nCompare == 0 )
{
// ヒット
return nIndex;
}
if( nCompare < 0 )
{
// 小さい側へ
nHigh = nIndex - 1;
}
else
{
// 大きい側へ
nLow = nIndex + 1;
}
}
return -1;
}
public static int SearchBlock( byte bySrc, byte byTarget, int nBlockLength )
{
int nIndex = BinarySearch( bySrc, byTarget, nBlockLength );
if( nIndex < 0 )
{
// 見つからなかった
return -1;
}
// 見つかった位置よりも前に一致するものを確認
int nBlockNum = bySrc.Length / nBlockLength;
while( nIndex > 0 )
{
int nOffset = nBlockLength * (nIndex - 1);
int nCompare = Compare( byTarget.Length, bySrc, nOffset, byTarget, 0 );
if( nCompare != 0 )
{
break;
}
nIndex --;
}
return nIndex;
}