读书人

终于搞清楚了C#二进制的一些关键操作了

发布时间: 2012-01-26 19:40:46 作者: rapoo

终于搞清楚了C#二进制的一些关键操作了,解决了微软面试题,求数组中两两之差绝对值最小的值O(N)最少内存限制的问题!
终于搞清楚了C#二进制的一些关键操作了,解决了微软面试题,求数组中两两之差绝对值最小的值O(N)最少内存限制的问题!

研究了好几天,写出来一个看起来象O(n)的算法,O(nlog)就不用写了.
思路是桶排序O(N)复杂度,为了节省空间,采用了Byte[]数组,1个byte代表8个数字的有无.
回头整理公布一下C#二进制运算的一些重要操作.

C# code
using System;namespace MinABS{    class Program    {        static void Main(string[] args)        {            int n = 100;            int[] a = new int[n];            Random rand = new Random();            int min = int.MaxValue;            int max = int.MinValue;            Console.WriteLine("产生了" + n + "个数据的实验数组,");            Console.WriteLine("本程序适用于int.MinValue到int.MaxValue范围,请自行修改输入的量和范围");            for (int i = 0; i < n; i++)            {                //赋值并且取到最大最小值                //a[i] = rand.Next(int.MinValue, int.MaxValue);                 a[i] = rand.Next(-100, 100);                if (a[i] < min) { min = a[i]; }                if (a[i] > max) { max = a[i]; }                 Console.Write(a[i] + " ");                            }             Console.WriteLine();            Console.WriteLine("在O(n)内得到最大最小分别是:");            Console.WriteLine(max + "和" + min);                        long offset = (long)max + Math.Abs((long)min);            //规划数组的长度。每个byte有8位长            int len = (int)(offset >> 3) +1 ;            Byte[] B = new Byte[len];            int kkkk = 0;            bool IsSame = false;//是否有重合点标记                       //O(n)的时间内分配到了Byte[]中。                        for (int i = 0; i < n; i++)            {                offset = (long)a[i] - (long)min;                int index = (int)(offset >> 3);                int temp = B[index];                //把末k位变成1                //把右数第k位变成1 例如:(00101001->00101101,k=3)     x | (1 << (k-1))                             int tempOffSet = (1 << (  (int)(offset & 7) ) );                //判断重合                if (!IsSame)                {                    kkkk = temp & tempOffSet;                    if ((temp & tempOffSet) >= 1)                    {                        IsSame = true;                        //如果0算最小距离就在这里退出吧。本代码判断重合,但没把0作为结果。                                            }                }                int bbb = B[index];                                B[index]  |=  (Byte)(tempOffSet);                          int aaa = B[index];              }            //最小距离初始为最大。            Console.WriteLine("在O(n)的时间内分配到了Byte[]中,正在计算最小距离,请稍候。。。。。");            long minABS = long.MaxValue;            long lastIndex = -1;            //在常数范围内循环,复杂度不增加。最坏的情况是32*int.MaxValue次。            for (int i = 0; i < B.Length; i++)            {                //if (B[i] == 0) { continue; }                //在常数范围内循环,复杂度不增加。                for (int k = 0; k < 8; k++)                {                    if (((B[i] >> k) & 1) == 1)                    {                        if (lastIndex >= 0)                        {                            long temp = ((long)i << 3) + k - lastIndex;                            if (temp < minABS)                            {                                minABS = temp;                               Console.WriteLine("目前得到了最小距离:" + minABS);                            }                        }                        lastIndex = (i << 3) + k;                                            }                }            }            if (IsSame)            { Console.WriteLine("有重合点"); }            else            { Console.WriteLine("无重合点"); }            Console.WriteLine("不考虑重合最小距离是:" + minABS);            Console.WriteLine("总复杂度是:O(n)");                        Console.ReadLine();        }    }}






------解决方案--------------------


sf
[解决办法]
sf
[解决办法]
学习
[解决办法]
学习
[解决办法]
牛人,
学习了

[解决办法]
楼主你是论坛的希望
[解决办法]
up
[解决办法]
楼主你是论坛的希望
[解决办法]
sf??
[解决办法]
超可爱的楼主[b][/b][size=24px][/size]
[解决办法]
楼猪你是论坛的希望~
[解决办法]
哈哈
[解决办法]
嗯,仔细看看
[解决办法]
漂亮。
[解决办法]
学习了
[解决办法]
^o^
[解决办法]
楼主你是论坛的希望~
[解决办法]
主害!
[解决办法]

[解决办法]
jf

读书人网 >C#

热点推荐