在日常我们经常要产生一个序号,但是通常产生的序号是不可回收的(暂且这么称呼吧),如,SQL数据库中字段设置为自增的情况下,产生的序号是连续的,但是当我们删除其中的记录之后,新增的记录的序号并不能继续使用已经删除的记录的序号,而是在原来的序号上继续自增。在一下大型的程序开发中,这个方式显然不是很合适。我们改怎么做才能重复利用已经废弃的序号呢?这也算是进行废物再利用,开玩笑的……
我的方法可能比较笨,谁有好的方法可以告知我改进……
我的做法是借鉴网络编程中某一节将的方法,具体的忘记了……我们都知道整数(int)在计算机中的表示4个字节(通常情况下,不同的操作系统定义可能不同),一个字节又使用8bit来表示的,因此我就想到使用整数的每一位的状态来表示这一位对应的序号的状态,使用还是未使用。其实就是将一个整数转化为bit数组,bit数组的每一项标示对应的数组下标表的整数对应的序号的状态。如,bit数组 a[3]=false;就是序号3没有使用,我们就可以返回数组下标3作为产生的序号。当我们使用了该序号就要将设置为a[3]=true;
每一次在产生序号的时候首先将整数转换为bit数组,然后遍历数组的每一位,直到检测第一个0或者false时,我们就返回对应的下标,通过将数组相应的项设置为1或者true。删除的时候同样个过程,只要找到对应的位置,设置为false或者0即可。
下面是源代码:
1、声明数组保存整数
private List<Int32> objNum = new List<Int32>() { 0 };
2、产生序号
private Int32 GenerateNum()
{
Int32 tt = 0;
Int32[] xx = new Int32[] { 0 };
BitArray ba = null;
Int32 j;
for (j = 0; j < objNum.Count; j++)
{
if (objNum[objNum.Count - 1] == -1)
{
objNum.Add(0);
}
xx[0] = objNum[j];
ba = new BitArray(xx);
for (Int32 i = 0; i < ba.Length; i++)
{
if (!ba.Get(i))
{
ba.Set(i, true);
tt = j * sizeof(Int32) * 8 + (i + 1);
break;
}
}
}
objNum[j - 1] = this.BitArrayToInt32(ba);
return tt;
}
3、删除序号
private void RemoveNum(Int32 num)
{
int inte = num / (sizeof(Int32) * 8); //整数部分
int deci = num % (sizeof(Int32) * 8);
BitArray ttba = null;
if (inte < objNum.Count)
{
Int32[] ttx = new Int32[] { objNum[inte] };
ttba = new BitArray(ttx);
ttba.Set(deci - 1, false);
}
objNum[inte] = this.BitArrayToInt32(ttba);
}
4、将Bit数组转换为整数
private Int32 BitArrayToInt32(BitArray bitArray)
{
//将BitArray 转换为Int32
Int32 ret = 0;
for (Int32 z = 0; z < bitArray.Length; z++)
{
if (bitArray.Get(z))
{
ret |= (1 << z);
}
}
return ret;
}
结束。有什么问题欢迎讨论……