c语言div是一种算法嘛,一道C语言笔试题的算法以及简单证明

如果n为偶数,则将它除以2,

如果n为奇数,则将它加1或者减1。

问对于一个给定的n,怎样才能用最少的步骤将它变到1。

例如:

n= 61

n-- 60

n/2 30

n/2 15

n++ 16

n/2 8

n/2 4

n/2 2

n/2 1

2,算法

输入:一个32bit无符号数in.

输出:经过DIV/ADD/SUB变为1的步骤.

注:

DIV--- /2操作;

ADD--- ++操作;

SUB--- --操作;

1),if (in==1)

转3);

else

转2);

2),if(in is even)

in = in DIV 2;

print div 操作;

else

令 res1 = in-1 中所包含的bit 1的个数;

令 res2 = in+1 中所包含的bit 1的个数;

if (res1<=res2)

in = in SUB 1;

print SUB 操作;

else

in = in ADD 1;

print ADD 操作;

endif

转1);

3),退出

3,证明

1),DIV/ADD/SUB三种运算,DIV是使in最快逼近1的运算;

2),使用DIV需要满足(in&1) == 0的条件,如果不能满足该条件,

只能使用ADD/SUB运算;

3),in包含的bit 1越多,就需要更多的ADD/SUB步骤;

在选择使用ADD/SUB运算过程中,将计算结果包含bit 1的

个数最少作为选择的标准,使得所选择的运算是当前步骤中

最优的.

附:算法的c源码(在linux下调试通过)

#include

#include

#include

/*

compute the number of the bit 1 in the para bits

*/

static unsigned int get_one_number(unsigned long bits)

{

unsigned int ret = 1;

while(bits &(bits-1))

{

ret++;

bits = bits & (bits-1);

}

return ret;

}

int main(int argc,const char* argv[])

{

unsigned long in = 0;

unsigned int out = 0;

in = strtoul(argv[1],NULL,10);

//  out = get_one_number(in);

//  printf("0x%8x have %4d bit1/n",in,out);

while(in!=1)

{

if (in&1UL)

{

unsigned long res1,res2;

res1 = get_one_number(in-1);

res2 = get_one_number(in+1);

if (res1<=res2)

{

printf("%8d(%8x) %8d(%8x) step=%s/n",in,in,in-1,in-1,"SUB");

in-=1;

}

else

{

printf("%8d(%8x) %8d(%8x) step=%s/n",in,in,in+1,in+1,"ADD");

in+=1;

}

}

else

{

printf("%8d(%8x) %8d(%8x) step=%s/n",in,in,in>>1,in>>1,"DIV");

in>>=1;

}

}

return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值