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

これは、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 result =calculate(284); //結果=128、128、16、8、4

于 2011-03-30T15:16:03.550 に答える
0

これは、擬似コードのかなり単純な反復ソリューションです。ここからもっと面白いところに持っていってみてください。再帰的に実行できます。整数をバイナリ表現に変換してその文字列を反復処理できます。LINQを使用して非常に簡潔に実行するための賢い方法があると想像してください。

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

PS-これは問題のシリーズを明示的に保存しません-それは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
    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 に答える