Board logo

标题: 【出题】批处理显示一个数等于哪些2的n次方数的和 [打印本页]

作者: 随风    时间: 2009-3-21 15:57     标题: 【出题】批处理显示一个数等于哪些2的n次方数的和

输入一个正整数(cmd范围内)显示它是哪些2的n次方数的和。
有点说不清楚,呵。。
举几个例子
如:
8=8
15=1+2+4+8
25=1+8+16
256=256
273=1+16+256

[ 本帖最后由 随风 于 2009-3-22 01:48 编辑 ]
作者: defanive    时间: 2009-3-21 16:58

次方运算还要自己写么。。。
2^31-1,30次,for就够用了。。。
作者: pusofalse    时间: 2009-3-21 18:21

这时候就能看出位运算的强大了啊。用位运算解此题,核心代码大概不会超过5行~
作者: 随风    时间: 2009-3-21 18:31     标题: 回复 3楼 的帖子

pusofalse兄所说的位运算,不知是否指获取2的n次方?
我的代码中发现用位运算还不如直接计算来的方便,到时期待兄的代码。
作者: pusofalse    时间: 2009-3-21 18:36

用到了两个位运算符,右移<<和与&,计算n次方是用了<<,分解出是哪些数的和用了按位相与&~
作者: 随风    时间: 2009-3-21 18:42     标题: 回复 5楼 的帖子

太期待了!!!!!!!!!!
作者: 随风    时间: 2009-3-21 22:37

终于知道如何用 位运算 来作了,谢pusofalse的指点。
作者: lhjoanna    时间: 2009-3-22 00:50

位运算的是不是类似这样:
  1. @echo off&setlocal enabledelayedexpansion
  2. set /p "number=请输入一个整数:"
  3. set /a flag=1,num=0
  4. set /p=!number!=<nul
  5. for /l %%i in (1 1 31) do (
  6.     set /a a="!number! & !flag!"
  7.     if !a! equ 1 set /a b="1<<!num!" & set /p=!b!+<nul
  8.     set /a num+=1,"number>>=1"
  9. )
  10. set /p= <nul & echo.
  11. pause>nul
复制代码
只能计算2*31-1(2147483648)以内的数,没考虑负数,对于负数按补码算倒不如当成正数算,最后再加个负号。

[ 本帖最后由 lhjoanna 于 2009-3-22 01:01 编辑 ]
作者: 随风    时间: 2009-3-22 01:08     标题: 回复 8楼 的帖子

是否不用这么麻烦,
另兄的代码还可精简。
  1. @echo off&setlocal enabledelayedexpansion
  2. set "x=!random!"
  3. set /p=!x!=<nul
  4. for /l %%i in (0 1 31) do (
  5.     set /a a="x&1","x>>=1"
  6.     if !a! equ 1 set /a b="1<<%%i"&set/p=!b!+<nul
  7. )
  8. set /p= <nul & echo.
  9. pause>nul
复制代码

[ 本帖最后由 随风 于 2009-3-22 01:18 编辑 ]
作者: zqz0012005    时间: 2009-3-22 01:13     标题: 回复 8楼 的帖子

嗯,大家都是这个时候在线啊。
http://www.bathome.net/viewthrea ... amp;page=1#pid24217
作者: lhjoanna    时间: 2009-3-22 01:27

看了zqz提供的链接,我的是麻烦了,num变量可以不用的,用%%i代替就可以。汗,2行就搞定了~还有一处小问题,就是for循环中应该是 0-30就可以了吧。
作者: pusofalse    时间: 2009-3-22 01:37

各位都好厉害,反倒是我的代码复杂了点~
  1. @echo Off & SetLocal EnableDelayedExpansion
  2. set "szResult="
  3. set /p "var=Input: "
  4. For /L %%a in (0 1 31) do (
  5.        set /a n = 1"<<"%%a, m = var "&" n
  6.        If !m! equ !n! set "szResult=!szResult!+!n!"
  7. )
  8. If defined szResult Echo %szResult:~1%
  9. Pause
复制代码

[ 本帖最后由 pusofalse 于 2009-3-22 01:52 编辑 ]
作者: 随风    时间: 2009-3-22 01:47     标题: 回复 12楼 的帖子

哈哈,但是都是以你的思路为核心啊,大家都放出代码来吧。。。
作者: pusofalse    时间: 2009-3-22 01:55

稍稍修改了下,只知1"<<"n 的结果是2的n次方,但不知1"<<"0的结果为何是1?~
结果陷入卡壳中,还计算出了“斐波那契”数列~

[ 本帖最后由 pusofalse 于 2009-3-22 02:09 编辑 ]
作者: lhjoanna    时间: 2009-3-22 02:00

我这里 1<<0 结果是1啊,兄如何测试的?
作者: lhjoanna    时间: 2009-3-22 02:01

对于刚刚的for循环次数的问题,为了测试,修改了下代码,用来查看其二进制位,如下:
  1. @echo off&setlocal enabledelayedexpansion
  2. set /p "number=input:"
  3. set /p=!number!=<nul
  4. for /l %%i in (0 1 31) do (
  5.     set /a a="number&1","number>>=1"
  6.     set "binary=!a!!binary!"
  7. )
  8. echo !binary!
  9. pause>nul
复制代码

可以输入的整数范围是-2147483648~2147483647,32位有符号整数,最高位表示符号位。
不过循环32次结果也正确,因为对于32位范围内的正数来说,最高位总是0。
作者: pusofalse    时间: 2009-3-22 02:08     标题: 回复 15楼 的帖子

不好意思,刚才大脑短路。。。 我这里也是1 - -||||




欢迎光临 批处理之家 (http://www.bathome.net/) Powered by Discuz! 7.2