在批处理脚本中执行模数运算
Posted
技术标签:
【中文标题】在批处理脚本中执行模数运算【英文标题】:Performing Modulus Arithmetic Within a Batch Script 【发布时间】:2016-12-07 11:52:36 【问题描述】:作为新事物,我正在尝试使用批处理脚本 (https://projecteuler.net/problem=5) 完成 Project Euler 问题 5。然而;我遇到了一些问题。如果有人可以检查我的代码,那就太好了。
@ECHO off
SET init=1
SET iter=1
SET /a func=%init% %% %iter%
cls
:Num
IF func==0 (
IF iter==20 (
ECHO Val = %init%
pause
exit
) ELSE (
SET /a iter+=1
GOTO Num
)
) ELSE (
SET iter=1
SET /a init+=1
GOTO Num
)
它的意思是检查init mod iter
是否返回0,如果是,则将iter
的值加1,直到达到21。但是;如果不等于 0,则迭代计数将设置回 0 并重新开始计算。
将要发生的事情的一个例子:
1 mod 1 = 0, Therefor add 1 to iter
1 mod 2 != 0, Therefor init is set to 0 and 1 is added to init
2 mod 1 = 0, Therefor add 1 to iter
2 mod 2 = 0, Therefor add 1 to iter
2 mod 3 != 0, Therefor init is set to 0 and 1 is added to init
等等等等。
发生了什么的一个例子:
1 mod 1 != 0, Therefor add 1 to init
2 mod 1 != 0, Therefor add 1 to init
3 mod 1 != 0, Therefor add 1 to init
等等等等。
任何帮助表示赞赏,谢谢。
【问题讨论】:
不过,我对代码做了一些更改;现在它完全跳过了模运算并说 1 mod 1 到 20 = 0。关于为什么这样做的想法?@ECHO off SET init=1 SET iter=1 SET /a func="%init% %% %iter%" cls :Num IF "%func%" == "0" ( IF "%iter%" == "21" ( echo. ECHO Val = %init% echo. echo Press any key to exit . . . pause > nul exit ) ELSE ( echo %init% mod %iter% = 0; CONT SET /a iter+=1 GOTO Num ) ) ELSE ( echo %init% mod %iter% != 0; BREAK SET iter=1 SET /a init+=1 GOTO Num )
很抱歉格式不好。
你永远不会重新计算%func%
。
我该如何合并这个?
将:Num
移动到SET /a func=%init% %% %iter%
的正上方
你的蛮力方法不实用。假设您制定了正确的语法和逻辑,我相信这种方法需要很多天,也许很多周才能完成。即使您优化代码以使用 FOR /L 循环而不是相对较慢的 GOTO,我相信也需要很多小时才能完成,可能超过一天。
【参考方案1】:
这个怎么样:
@Echo off
setlocal enabledelayedexpansion
SET init=1
SET iter=1
cls
set loopCounter=1
set loopBatch=1
:numLoop
SET /a func="!init! %% !iter!"
IF !iter! == 21 (goto :done)
IF !func! == 0 (call :incIter) ELSE ( call :incInit)
SET /a loopCounter+=1
SET /a loopBatch="%loopCounter% %% 1000"
if !loopBatch! == 0 (echo %loopCounter% iterations done)
goto :numLoop
:incInit
rem echo %init% mod %iter% == %func%; Increasing init
SET iter=1
SET /a init+=1
goto :eof
:incIter
rem echo %init% mod %iter% == %func%; Increasing iter
SET /a iter+=1
goto :eof
:done
echo.
ECHO Val = %init%
【讨论】:
【参考方案2】:只是发布一个“实用”(!?)解决方案,以防万一有人发现它“有用”(!!?)
@echo off
setlocal enableextensions enabledelayedexpansion
rem Our search limit
set "limit=20"
rem Note: batch arithmetic is limited to 2^31 values, so 26 is the highest
rem value that we can directly use
rem Initialize searched number
set "euler5=1"
rem Initialize list of numbers for a Erastotenes cribe
for /l %%a in (2 1 %limit%) do set "f.%%a=%%a"
rem Search for prime numbers and simplify (divide) greater multiples
rem Keep multiplying as we iterate over the list
for /l %%a in (2 1 %limit%) do (
if !f.%%a! gtr 1 (
set /a "euler5*=!f.%%a!"
for %%c in (!f.%%a!) do for /l %%b in (%%a %%a %limit%) do (
set /a "f.%%b/=%%c"
)
)
)
rem Echo solution
echo %euler5%
【讨论】:
【参考方案3】:根据此链接:link 有一个模运算符。
所以你可以试试这个
@echo off
::we should start with 21 because we know that all numbers from 1-20
::cannot be divided by 20 all 20 times.
::This will also fix the problem of an unwanted a zero remainder at the
::early numbers
set count=21
set divide=1
::We need to set enabledelayedexpansion so we can use ! as a varible
::expander.
setlocal enabledelayedexpansion
:loop
:: begin the modulus operator.
set /a remainder=!count!%%!divide!
if %remainder%==0 (
if %divide%==20
::Yea!
echo number found:%count%
::Don't forget to pause
::or else you cant see the number.
pause
) else (
set /a divide=%divide%+1
::equivelent to set /a divide+=1
goto :loop
)
) else (
set /a count=%count%+1
goto :loop
)
虽然这不能修复您的脚本,但它绝对是一种更快的方法。
【讨论】:
以上是关于在批处理脚本中执行模数运算的主要内容,如果未能解决你的问题,请参考以下文章