首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从数组中求取给定数目之和值的算法

从数组中求取给定数目之和值的算法
EN

Stack Overflow用户
提问于 2017-08-02 13:29:46
回答 4查看 1.4K关注 0票数 6

我不知道搜索或谷歌,所以我问它在这里。我有一个具有固定大小的整数数组,完全符合这个逻辑。

代码语言:javascript
复制
sample [1,2,4,8,16,32]

现在我得到了一个数字,例如26。我会找到这个数字之和为2,8,16的数字。

对20个人来说是4,16。

40是8,32

对63人来说,所有这些数字都是1,2,4,8,16,32

正确的算法是什么?

我严格地知道,总有这样的延续,这个数字是前一个值的两倍。此外,只有来自给定数组的数字才能与给定的数字相加,并且每个数字只使用一次或不使用一次。

如果它将在C#方法中,它将接受int数组和int值,并返回包含从给定数组中将该数字相加的int数组。

谢谢

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2017-08-02 13:54:00

正如您所看到的,这个数字是基-2,这意味着您可以很容易地使用移位

你可以试试这个:

代码语言:javascript
复制
private IEnumerable<int> FindBits(int value)
{
    // check for bits.
    for (int i = 0; i < 32; i++)
    {
        // shift 1 by i
        var bitVal = 1 << i;   // you could use (int)Math.Pow(2, i); instead
        // check if the value contains that bit.
        if ((value & bitVal) == bitVal)
            // yep, it did.
            yield return bitVal;
    }
}

此方法将检查设置了哪些位,并将它们作为i枚举返回。(可以转换为列表数组)

用法:

代码语言:javascript
复制
// find the bits.
var res = FindBits(40).ToArray();

// format it using the string.join
var str = $"[{string.Join(",", res)}]";

// present the results
Console.WriteLine(str);

[8,32]的结果

额外信息:

代码语言:javascript
复制
                          counter
00000001 =   1     = 1 << 0
00000010 =   2     = 1 << 1 
00000100 =   4     = 1 << 2
00001000 =   8     = 1 << 3
00010000 =  16     = 1 << 4
00100000 =  32     = 1 << 5
01000000 =  64     = 1 << 6
10000000 = 128     = 1 << 7

而不是写所有的组合,你做了一个for循环,它做计数器。

一些额外的非理性:

如果您喜欢lambda,可以用以下内容替换FindBits:

代码语言:javascript
复制
private Func<int, IEnumerable<int>> FindBits = (int value) => Enumerable
    .Range(0, 31)
    .Select(i => 2 << i).Where(i => (value & i) == i);

但最好保持它的辛佩尔/可读性。

票数 4
EN

Stack Overflow用户

发布于 2017-08-02 13:58:31

首先你应该注意到

代码语言:javascript
复制
 ( 1    2    4    8    16 ... ) = (2^0  2^1  2^2  2^3  2^4 ... )

这和为十进制数找到二进制编码是一样的。您要寻找的是一种将十进制或基数10数字转换为二进制或基2数的算法。

算法非常简单:

代码语言:javascript
复制
public List<int> dec_to_bin(int num)
{
    List<int> return_list = new List<int>();
    int index = 0; 
    int remainder = num;
    int bit = 0;

    while (remainder > 0)
    {
        bit = remainder % 2;

        if (bit == 1 )
        {
            return_list.Add((int)Math.Pow(2, index));
        }

        remainder = remainder / 2; 
        index = index + 1;
   }

   return return_list;
}

但是,有一种更好的方法,只使用已经是二进制的数字的底层编码。

代码语言:javascript
复制
public List<int> dec_to_bin(int num)
{
    List<int> return_list = new List<int>();
    int value = 1; 

    while( value < num )
    {
         if( (value & num) == value )
         {
             return_list.Add(value);
         }
         value = value * 2; 
    }
    return return_list;
}
票数 2
EN

Stack Overflow用户

发布于 2019-02-13 22:54:45

另一种声明您的要求的方法是“2的唯一幂与给定的整数之和是什么?”由于计算机以2的本地能力工作,在大多数语言中都有内置的好东西可以非常简洁地完成这一任务。

另外,您可以使用现有的.Net类型和方法来消除编写自己的循环的需要。

这里有一个方法:

代码语言:javascript
复制
IEnumerable<int> GetCompositePowersOf2(int input) =>
    //convert to enumerable of bools, one for each bit in the 
    //input value (true=1, false=0)
    new BitArray(new[] { input }).Cast<bool>()
    // get power of 2 corresponding to the position in the enumerable 
    // for each true value, gets 0 for false values.
    .Select((isOne, pos) => isOne ? (1 << pos) : 0)
    //filter out the 0 values
    .Where(pow => pow > 0);
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45462286

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档