求任何一个正数的组合,组合的规则是这个数等于1或2的整数幂之和,请列出组合的情况。

比如:

11 = 1,2,8
26 = 2,8,16

31 = 1,2,4,8,16

96 = 64,32

 
1.拆分法
分析:把10进制数转换2进制
11 = 1,2,8         -> 1011 = 1,10,100
31 = 1,2,4,8,16  -> 11111 = 1,10,100,1000,10000

96 = 64,32        -> 1100000 = 100000,1000000

是不是看出了点规律呢? 对,任何10进制数转换成2进制后,都能按位从右到左遇1拆分,拆分的结果,转换成10进制,正好就是求解的组合。因为2的整数幂转换成2进制后正好是1开头,之后全是0. 比如:1,2,4,8 -> 1,10,100,1000
实现:

List<int> GetCombines(int number)
        {
            List<int> combines = new List<int>();
            string str = Convert.ToString(number, 2);
            for (int i = 0; i <= str.Length - 1; i++)
            {
                if (str[i] == '0') continue;
                string s = Math.Pow(10, str.Length - i - 1).ToString("F0");
               combines.Add(Convert.ToInt32(s, 2));
            }

            return combines;
        }
 
2. 穷举法
 分析:把10进制数N转换2进制,从1开始穷举2的整数幂,会发现与N的2进制与运行后,结果不等于0的正好是N的2进制组成成员。
实现:

        List<int> GetMask(int number)
        {
            List<int> mask = new List<int>();
            int baseElement = 1;
            int sumOfElement = 0;
            while (sumOfElement < number)
            {
                if ((baseElement & number) != 0)
                {
                    sumOfElement += baseElement;
                    mask.Add(baseElement);
                }
                baseElement = baseElement * 2;
            }
            return mask;
        }