3

我有一系列这样的数字:[1 2 4 8 16 32 64 128],如果我输入一个数字,即 66,那么输出应该是 64 和 2。如果我输入 87,那么输出应该是 64、16、4、2、1。

(基本上,它首先除以可能的最大数,找到余数,然后继续除以可能的最大数,直到余数为 0。或者另一种方式可能只是减去可能的最大数,然后像这样继续减去,直到达到0.)

我正在考虑一个递归函数,但不太确定。有什么帮助吗?

谢谢。

4

9 回答 9

11
class Program
{
    [Flags]
    enum Bits
    {
        _1 = 1,
        _2 = 2,
        _4 = 4,
        _8 = 8,
        _16 = 16,
        _32 = 32,
        _64 = 64,
        _128 = 128
    }

    static void Main(string[] args)
    {
        var b = (Bits)87;
        Console.WriteLine(b);
        Console.ReadKey();
    }
}
于 2011-03-30T15:14:37.877 回答
3

这是迭代版本

public static IEnumerable<int> FindIndex(int input)
{
    var power = 0;
    while (input > 0)
    {
        var digit = input % 2;
        if (digit == 1)
        {
            yield return (int)Math.Pow(2, power);
        }
        input /= 2;
        power++;
    }
}

这是递归版本

public static void FindIndexRec(int input, int power, ICollection<int> numbers)
{
    if (input == 0)
    {
        return;
    }
    var digit = input % 2;
    if (digit == 1)
    {
        numbers.Add((int)Math.Pow(2, power));
    }
    FindIndexRec(input / 2, ++power, numbers);
}

你可以这样称呼它

var numbers = new List<int>();
FindIndexRec(input, 0, numbers);
于 2011-03-30T15:52:22.413 回答
2

您可以使用位掩码。事实上,从头开始 - 你应该使用位掩码!几乎可以肯定,这就是错误代码的创建方式,也是应该将其分开的方式。其他任何事情都极有可能使您的其他程序员的听众感到困惑。

我没有声称代表所有程序员,也没有声称自己有任何好处,但我是一名程序员,所有其他答案都让我感到困惑。这显然是一个按位的“问题”,那么为什么要混淆呢?

甚至不需要将结果存储在任何地方,因为每次重新计算它都一样快,如下所示:

for(int i=0;i<8;++i) {
    if((error&(1<<i))!=0 {
        // 1<<i is in the resulting list.
    }
}
于 2011-03-30T18:08:00.553 回答
0

Here's a pretty naive iterated solution in pseudocode. Try to take it somewhere more interesting from here. You can do it recursively, you can convert the integer to binary representation and iterate on that string, id imagine theres a clever way to do it with LINQ very concisely, etc.

v = inputNumber
while(v > 0):
     temp = greatest power of 2 less than v
     print temp
     v -= temp

PS - this does not explictly store the series in question - it presumes powers of 2.

于 2011-03-30T14:58:15.423 回答
0
    string calculate(int input)
    {
        string output = string.Empty;
        int[] series = new int[] { 1, 2, 4, 8, 16, 32, 64, 128 };
        foreach (int i in series.Reverse<int>())
        {
            if (input >= i)
            {
                output += i.ToString() + " ";
                input -= i;
            }
        }
        return output;
    }
于 2011-03-30T15:03:57.203 回答
0
List<int> additives = new List<int>()
List<int> sourceNumbers = new List<int> { 1, 2, 4, 8, 16, 32, 64, 128 };

int sourceNumber = 87;

foreach(var number in sourceNumbers.Reverse())
{
    if(sourceNumber % number > 0)
    {
       additives.Add(number);
       sourceNumber -= number;
    }
    else
    {
       additives.Add(number);
       break;
    }
}
于 2011-03-30T15:04:57.187 回答
0

这将适用于大于 256 的输入数字:

   int[] calculate(int input)
    {
        List<int> retVal = new List<int>();
        string output = string.Empty;
        int[] series = new int[] { 1, 2, 4, 8, 16, 32, 64, 128 };
        foreach (int i in series.Reverse<int>())
        {
            while (input >= i)
            {
                retVal.Add(i);
                input -= i;
            }
        }

        return retVal.ToArray();
    }

例如:var 结果 = 计算(284);// 结果 = 128, 128, 16, 8, 4

于 2011-03-30T15:16:03.550 回答
0
    IEnumerable<int> GetFlags(int input,IEnumerable<int> series)
    {
        foreach (int value in series)
            if ((input & value)==value)
                yield return value;
    }

或者LINQ解决问题。

IEnumerable<int> GetFlags(int input, IEnumerable<int> series)
{
    return series.Where(x => (x & input) == x);
}
于 2018-01-10T17:29:58.880 回答
0

抛开编程不谈,你也可以从数学上看。它基本上是 2 的(整数值)的幂log(2, input)

把它放在一个递归函数中当然很容易,它甚至看起来简单而流畅,但我怀疑它的计算复杂度不那么高,而且它肯定对你的作业没有帮助,只是想我会把它扔在这里。

于 2018-01-10T18:06:30.780 回答