求一个2的n次方的算法

快40的码农 2015-07-12 12:02:36
已知n={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21}
比如1060=2的2次方+2的5次方+2的10次方
67601=2的0次方+2的4次方+2的11次方+2的16次方

现在我知道一个数值67601,
求一个算法,算出该值是由哪几个2的几次方相加得到的(即等式中标红的数字。数字个数不确定,但应该是唯一的)。
...全文
1647 28 打赏 收藏 转发到动态 举报
写回复
用AI写文章
28 条回复
切换为时间正序
请发表友善的回复…
发表回复
Feather-b 2015-07-20
  • 打赏
  • 举报
回复
如果是3的话,可以分一下情况,待求数减1如果能被3整除,还是用求2的方法,如果不能整除,那就没有结果。手机打字,才开始自学编程,说得不对的地方多交流^_^
Feather-b 2015-07-20
  • 打赏
  • 举报
回复
我觉得还可以用待求值把每一次的2的n次方的公约数提出来,就是2的n次方的一个加数,然后待求值减去提出来的2的n次方,剩下的按照此方法循环一直到待求数等于0,提出来的几个2的n次方就是结果。前提讨论一下奇偶就可以了。
一转程序员 2015-07-16
  • 打赏
  • 举报
回复
引用 1 楼 xuzuning的回复:
            var v = 67601;
var s = Convert.ToString(v, 2);
for (int i=s.Length-1, n=0; i>=0; i--, n++)
{
if(s[i] == '1') Console.Write("{0} ", n);
}
hello728 2015-07-15
  • 打赏
  • 举报
回复
楼上的是不是用下1L的,改为3怎样
xx87343133 2015-07-15
  • 打赏
  • 举报
回复
解法类似2楼,但不需要转字符串

  int i = 0;
  while(i<32){
   if(n != ((n<<i)>>i)){
     printf(i);
  }
  i++;
  n = (n<<i)>>i;
}
fudapeng7 2015-07-15
  • 打赏
  • 举报
回复
引用 1 楼 xuzuning 的回复:
            var v = 67601;
            var s = Convert.ToString(v, 2);            
            for (int i=s.Length-1, n=0; i>=0; i--, n++)
            {
                if(s[i] == '1') Console.Write("{0} ", n);
            }
膜拜~~~~~~~这条件未限制导致结果不唯一,但是这大神给出了最牛逼的解决算法
Conmajia 2015-07-15
  • 打赏
  • 举报
回复
最简单的数值权值。。。我不知道楼上那么多人啪啪啪写那么多干嘛
王亨 2015-07-15
  • 打赏
  • 举报
回复
if(i=1;i<=n-1;i++) x=2*2;
_Tango 2015-07-15
  • 打赏
  • 举报
回复

#include <stdio.h>
#include <stdlib.h>

int main(int argc,char *argv[])
{
        if(argc != 2)
                return 1;
        int i;
        int num = atoi(argv[1]);
        printf("number %d = ",num);
        for(i = 0;i < 32;i++) {
                if((num >> i) & 0x00000001)
                        printf("2^%d + ",i);
        }
        putchar('\n');
}
猴头 2015-07-14
  • 打赏
  • 举报
回复
都挺厉害,我就没想到呢, 如果 求一个数 是不是 几个 3 的 几次方的和呢?????
欢乐的小猪 2015-07-13
  • 打赏
  • 举报
回复
余2 除2 计数加1 满足条件保存计数
zbdzjx 2015-07-13
  • 打赏
  • 举报
回复
引用 6 楼 SuperMan_ 的回复:
[quote=引用 楼主 SuperMan_ 的回复:] 已知n={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21} 比如1060=2的2次方+2的5次方+2的10次方 67601=2的0次方+2的4次方+2的11次方+2的16次方 现在我知道一个数值67601, 求一个算法,算出该值是由哪几个2的几次方相加得到的(即等式中标红的数字。数字个数不确定,但应该是唯一的)。
还是csdn上牛哥多,我这个是数据库中的一个字段的方向解析,能不能通过oracle的function写出来呢[/quote]
DECLARE
  TempValue NUMBER(10);
  i number(10);
BEGIN
  TempValue:=67601;
  i:=1;
  while TempValue>0 loop
    if TempValue mod 2 =1 then
      dbms_output.put_line(i-1);
    end if;
    i := i + 1;
    TempValue := (TempValue - TempValue mod 2)/2;
  end loop;
END;
snow__001 2015-07-13
  • 打赏
  • 举报
回复
十进制转化为二进制
老李家的小二 2015-07-13
  • 打赏
  • 举报
回复
都是大牛( ⊙o⊙ )哇
xuzuning 2015-07-12
  • 打赏
  • 举报
回复
            var v = 67601;
var s = Convert.ToString(v, 2);
for (int i=s.Length-1, n=0; i>=0; i--, n++)
{
if(s[i] == '1') Console.Write("{0} ", n);
}
风靡义磊 2015-07-12
  • 打赏
  • 举报
回复
二进制嘛,逻辑右移就行了
  • 打赏
  • 举报
回复
呵呵,重新看了一下,我弄了一个“不能停止”的死循环。所以需要修正一下上面的代码
private static IEnumerable<int> N进制(int n, int toBase)
{
    var cnt = 0;
begin:
    if (n == 0)
        yield break;

    if (n % toBase == 1)
        yield return cnt;

    n /= toBase;
    ++cnt;
    goto begin;
}
  • 打赏
  • 举报
回复
对于 .net 的 Convert.ToString 来说,转为 2 进制字符串时,它直接调用了 Windows SDK 的 IntToString 函数来计算,不是使用.net framework来计算的。你的所谓 Oracle也一样地支持原生的10进制与2进制的转换。 这里最主要地是看懂背后的东西。你的数学老师可以看不懂计算机最基本的二进制的概念,因为他不编程。说明你不要跟数学老师学编程了。
  • 打赏
  • 举报
回复
引用 8 楼 SuperMan_ 的回复:
[quote=引用 2 楼 starfd 的回复:] 参考2L,其实没算法,只要转化成2进制的字符串,然后循环一次就可以了
难怪,我还找哦了数学老师让给讲解下怎么求解,结果人家说这个算不出答案。看来是思路不对[/quote] 嗯,你们数学老师肯定没有学过计算机原理课程。2进制数字的概念应该是个任何级别的资格考试必考的最基本概念(如果不考,那是懒得考)。 由于计算机本身就是二进制的,所以机器语言支持其数据结构、移位和各种运算,因此对于2、4、8、16、32进制等等计算都直接使用二进制的移位操作等等直接的操作。 而如果是更广泛一点,对于n进制,你可以这样来“移位”计算每一个位置cnt上的结果
private static IEnumerable<int> N进制(int n, int toBase)
{
    var cnt = 0;
begin:
    if (n % toBase == 1)
        yield return cnt;

    n /= toBase;
    ++cnt;
    goto begin;
}
例如可以写
foreach (var x in N进制(67601, 3))
    Console.WriteLine(x);
江南小鱼 2015-07-12
  • 打赏
  • 举报
回复
引用 1 楼 xuzuning 的回复:
            var v = 67601;
            var s = Convert.ToString(v, 2);            
            for (int i=s.Length-1, n=0; i>=0; i--, n++)
            {
                if(s[i] == '1') Console.Write("{0} ", n);
            }
利用二进制和十进制的转换,很巧妙的得到答案。
加载更多回复(7)

110,537

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧