从数组中,找出所有的,二数和为sum的数,不重复
-10 到 10 ,和为5的有 0,5 1,4 2,3 -1,6 -2,7 -3,8 -4,9 -5,10
class Program
{
static void Main()
{
Console.WriteLine("create array integer");
int[] arr = new int[100000000];//要计算的数组
Random r = new Random();
for (int i = 0; i < arr.Length; ++i)
{
arr[i] = r.Next(int.MinValue, int.MaxValue);//产生随机数
}
DateTime dt1 = DateTime.Now;
Console.WriteLine("starttime: {0}", dt1);
ArrayFind2.find(arr, 0);//查找
DateTime dt2 = DateTime.Now;
Console.WriteLine("endtime: {0}, totaltime: {1}.", dt2, dt2 - dt1);
Console.Read();
}
}
public class ArrayFind2
{
static long half = 2147483648L;
static int len = (int)(2 * half / 8);
static byte[] keys = new byte[] { 0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80 };
static byte[] others = new byte[] { 0x1 ^ 0xff, 0x2 ^ 0xff, 0x4 ^ 0xff, 0x8 ^ 0xff, 0x10 ^ 0xff, 0x20 ^ 0xff, 0x40 ^ 0xff, 0x80 ^ 0xff };
public static void find(int[] arr, int sum)
{
Console.WriteLine("sf init ");
DateTime s = DateTime.Now;
//512MB
byte[] flag = new byte[len];
//设置标记
//如果按 ...flag[3],flag[2],flag[1],flag[0] 这样排列,0对应从右边数据,第half个位(bit)
//int.MinValue 对应 右边第一位(bit),int.MaxValue对应左边第一位(bit)
//bit上,1表示这数存在,0则不存在
foreach (int k in arr)
{
//flag[(half + k) / 8] |= keys[(half + k) % 8];
flag[(half + k) >> 3] |= keys[(half + k) & 0x7];
}
Console.WriteLine(string.Format("init end {0}\nfind start ", (DateTime.Now - s)));
s = DateTime.Now;
foreach (int one in arr)
{
//先看i是否已计算过
//加个条件,i!=sum-i,并且i存在(防有重复)
if ((flag[(half + one) >> 3] & keys[(half + one) & 0x7]) != 0 && sum != 2 * one)
{
//另一个娄
int other = sum - one;
//看另一个数是否存在
if ((flag[(half + other) >> 3] & keys[(half + other) & 0x7]) != 0)
{
//如果存在,将二个数设置为不存在
flag[(half + one) >> 3] &= others[(half + one) & 0x7];
flag[(half + other) >> 3] &= others[(half + other) & 0x7];
//Console.WriteLine(one + "," + other);//找出一对结果
}
}
}
Console.WriteLine("find end " + (DateTime.Now - s));
}
}