批量编号

时间:2012-12-11 06:25:13

标签: batch-file

我一直在使用批处理文件处理一个小项目,但我遇到了一个问题。据我所知,没有办法检查某个变量是否为素数,如果我错了会有人请告诉我如何这样做,否则,任何人都可以想到一个变通方法我可以使用(比如检查一个数字是否等于txt文件中素数列表中的数字或其他)。 谢谢^^ (另外值得注意的是我对批处理文件知之甚少,所以请原谅我可能出现的任何白痴......)

8 个答案:

答案 0 :(得分:3)

如果你有一个素数的文本文件,每行1个(显然达到某个限制),那么解决方案很简单 - 只需使用FINDSTR。

假设您有一个包含数字的NUMBER变量,那么

>nul findstr /x %NUMBER% "primes.txt" && (
    REM prime actions go here
    echo %NUMBER% is prime
) || (
    REM not prime actions go here
    echo %NUMBER% is NOT prime
)


更新

这是一个本机批处理脚本,可以测试批处理(有符号32位整数)支持的任何有效整数,看它是否为素数。性能比我想象的要好得多。

::testPrime  Number
::
::  Computes whether Number is a prime or not.
::  The result is printed to stdout.
::
::  ERRORLEVEL is also set to indicate the result:
::    0 = Prime
::    1 = Not Prime
::    2 = Error
::
::  Number = Any valid integral expression supported by SET /A
::
@echo off
if "%~1"=="test" (
  setlocal enableDelayedExpansion
  for /l %%N in (3 2 0x7fffffff) do (
    set /a "test1=num %% %%N, test2=%%N*%%N"
    if !test1! equ 0 exit 1
    if !test2! gtr !num! exit 0
  )
)

setlocal disableDelayedExpansion
2>nul set /a "num=%~1" || (
  >&2 echo invalid number: %1
  exit /b 2
)
if %num% leq 1 (
  echo %num% is NOT prime
  exit /b 1
)
if %num% leq 3 (
  echo %num% is prime
  exit /b 0
)
2>nul set /a "1/(num %% 2)" || (
  echo %num% is NOT prime
  exit /b 1
)
(
  cmd /c "%~f0" test
) && (
  echo %num% is prime
  exit /b 0
) || (
  echo %num% is NOT prime
  exit /b 1
)
exit /b

测试实际上分为两部分,第二部分实际上是在一个新的CMD实例中运行。第二部分实际上出现在脚本的顶部。这是出于性能原因而完成的。这是我在不终止批处理脚本的情况下立即突破FOR / L循环的唯一方法。

您可以轻松地将代码与脚本集成。例如:

@echo off
::----------------------------------------------------
:: This 2nd part of :testPrime must be at top of script
::
if "%~1"=="test" (
  setlocal enableDelayedExpansion
  for /l %%N in (3 2 0x7fffffff) do (
    set /a "test1=num %% %%N, test2=%%N*%%N"
    if !test1! equ 0 exit 1
    if !test2! gtr !num! exit 0
  )
)
:: End of 2nd part of :testPrime
::-----------------------------------------------------
:: Your code goes here
:: I'll just call the test with some representative values
::
setlocal disableDelayedExpansion
for %%N in (
  1 2 3 4 100001 100003 5000009 5000011 0x7fffffff-2 0x7fffffff
) do  >nul call :testPrime %%N && (
  rem prime number actions go here
  echo %%N is prime!
) || (
  rem non-prime number actions go here
  echo                           Not prime (%%N^)
)
exit /b

::----------------------------------------------------
:: Here is the 1st part of :testPrime
::
:testPrime
2>nul set /a "num=%~1" || (
  >&2 echo invalid number: %1
  exit /b 2
)
if %num% leq 1 (
  echo %num% is NOT prime
  exit /b 1
)
if %num% leq 3 (
  echo %num% is prime
  exit /b 0
)
2>nul set /a "1/(num %% 2)" || (
  echo %num% is NOT prime
  exit /b 1
)
(
  cmd /c "%~f0" test
) && (
  echo %num% is prime
  exit /b 0
) || (
  echo %num% is NOT prime
  exit /b 1
)
exit /b

上面的输出如下所示:

                          Not prime (1)
2 is prime!
3 is prime!
                          Not prime (4)
                          Not prime (100001)
100003 is prime!
                          Not prime (5000009)
5000011 is prime!
                          Not prime (0x7fffffff-2)
0x7fffffff is prime!

最后,只是为了yucks,我写了一个变体,列出了下一个素数> =或< =给定的数字。

::nextPrime [/less]  Num
::
::  List the minimum prime number >= Num
::
::  The /L option lists the maximum prime number <= Num
::
::  The ERRORLEVEL is set to the found prime number
::
::  Num = Any valid integral expression supported by SET /A
::
@echo off
setlocal enableDelayedExpansion
if "%~1"=="test" (
  for /l %%N in (3 2 0x7fffffff) do (
    set /a "test1=%2 %% %%N, test2=%%N*%%N"
    if !test1! equ 0 exit 1
    if !test2! gtr %2 exit 0
  )
)
if "%~1"=="prev" (
  if !num! lss 2 exit 0
  set /a "test=num%%2"
  if !test! equ 0 set /a num-=1
  for /l %%N in (!num! -2 2) do cmd /c "%~f0" test %%N && exit %%N
  exit 0
)
if "%~1"=="next" (
  if !num! lss 2 exit 2
  set /a "test=!num!%%2"
  if !test! equ 0 set /a num+=1
  for /l %%N in (!num! 2 0x7fffffff) do cmd /c "%~f0" test %%N && exit %%N
  exit 0
)
set "cmd=next"
if /i "%~1" equ "/L" (
  set "cmd=prev"
  shift /1
)
2>nul set /a "num=%~1" || exit /b 0
cmd /c "%~f0" %cmd% || echo !errorlevel!

以下是输出用法的演示:

D:\test>nextPrime 10000000
10000019

D:\test>nextPrime /l 10000000
9999991

答案 1 :(得分:1)

所有这些脚本对我来说都很糟糕(并且不必要)。

更简单的方法是使用......我相信我正在寻找的术语是模数或模数表达式(我认为模数是复数或模数)。

@echo off & setlocal enabledelayedexpansion

:a
cls
set /p num=Type a number to be checked: 
cls
set num2=%num%-1

if %num% leq 2 goto yes
for /l %%i in (2,1,%num2%) do (
    set rem=%num% %% %%i
    if %rem% neq 0 goto no
)

:yes
echo %num% is a prime number.
pause
goto a

:no
echo %num% is not a prime number.
pause
goto a

基本上,它获取一个用户定义的变量,并在除以数字时检查余数(rem)是否为0。

这种方式有点慢,但代码最短。您可以通过在if循环之前添加另一个for语句来缩短它,以便在除以2时检查数字是否有余数。

希望它有所帮助。

答案 2 :(得分:1)

另一位优秀的首席记者,如果您有耐心,这个人不会使用文件,可以达到64,000,000。保留环境变量中的素数除数列表。如果我有一个批量整数平方根例程,我可以使它更快。

@echo off
::batch prime list up to 64M by Antoni Gual
:: does not use files!!

setlocal enabledelayedexpansion
set bitmap=
set n=Y
set /a test=3,npri=3
echo 1th prime is 2 & echo 2th prime is 3 

:nextpri
set /a test+=2,index=0,div=3
if %test% LSS 8000 set bitmap=%bitmap%%n%
if %test% gtr 64000000 exit /b 

:nextest
if "!bitmap:~%index%,1!"=="N" goto nextdiv
set /a resi=!test!%%!div!
if %resi% equ 0 set n=N& goto nextpri

:nextdiv
set /a index+=1, div+=2
set /a div2=div*div 
if %div2% gtr %test% (
set n=Y
echo %npri%th prime is %test% 
set /a npri+=1 
goto nextpri)
goto nextest 

答案 3 :(得分:0)

以下脚本不执行素性测试。相反,它会生成一个特定边界的素数(在这种特殊情况下为硬编码的1000)。您可以生成一次列表,然后在脚本中使用它:

@echo off
echo 2
echo 3
echo 2 > primenos.txt
echo 3 >> primenos.txt
set current=3

:numbercalc
set tim=3
set /a max=%current%/5

:try
set /a t=%current%/%tim%
set /a u=%t%*%tim%
if %u% EQU %current% goto noprime
set /a tim+=2
if %tim% GTR %max% goto endtry
goto try

:endtry
echo %current%
echo %current% >> primenos.txt

:noprime
set /a current+=2
if %current% GTR 1000 goto end
goto numbercalc

:end
pause

取自here ......

答案 4 :(得分:0)

假设你有一个带有素数的文本文件(每行一个数字),你可以这样做:

@echo off
if "%1"=="" (echo Syntax: %~nx0 number & exit /b 2)
for /F "tokens=*" %%p in (primes.txt) do (
    if %%p EQU %1 (
        echo %1 is prime!
        exit /b 0
    )
)
echo %1 is not prime!
exit /b 1

示例通话:isprime.cmd 2会为您提供2 is prime!

答案 5 :(得分:0)

这就是我所做的。它找到所有素数高达214748,但它准确快速,并将结果输出到一个名为“pn.txt”的文件,当前数字输出到“cn.txt”(这是为了让我知道它的限制是什么):

(@echo off)&((set n=3)&((set tn=%n%)&((set d=2)&((set d2=)&((set m=100)&((echo.prime-numbers>pn.txt)&((echo. >>pn.txt)&((echo.1>>pn.txt)&((echo.2>>pn.txt)&((echo.1)&((echo.2)&(goto a))))))))))))

:a
(echo.%n%cn.txt)&((set tn=%n%)&(set tn=%n:~-1%))
(if %tn%==2 ((set /a n=%n%+1)&((set d=2%d2%)&(goto a))))&((if %tn%==4 ((set /a n=%n%+1)&((set d=2%d2%)&(goto a))))&((if %tn%==6 ((set /a n=%n%+1)&((set d=2%d2%)&(gotoa))))&((if %tn%==8 ((set /a n=%n%+1)&((set d=2%d2%)&(goto a))))&((if %tn%==0 ((set /a n=%n%+1)&((set d=2%d2%)&(goto a))))&(goto b)))))

:b
((set /a tn=%d%*%d%)&(if /i %tn% equ %n% ((set /a n=%n%+1)&((set d=2%d2%)&(goto a)))))&((if /i %tn% gtr %n% ((set tn=%n%)&((set l=%d%)&((if /i %n% equ 10000 (set d2=0))&((if /i %n% equ 100000 set (d2=00))&((set d=2%d2%)&((set m=100%d2%)&(goto d)))))))&((set /a d=%d%+1)&(goto b))

:d
(title verifing %n% at %d%)&(set tn=%n%)
set /a tn=%tn%*%m%
set /a tn=%tn%/%d%
set tn=%tn:~-2%
(if /i %tn% equ 00%d2% ((set /a n=%n%+1)&((set d=2%d2%)&(goto a))))&(((set /a tn=%n%-1)&(if %d%==%tn% ((echo.%n%)&((echo.%n%>pn.txt)&(((set /a n=%n%+1)&((set d=2%d2%)&(goto a)))))))&(if %d%==%l% ((echo.%n%)&((echo.%n%>pn.txt)&((set /a n=%n%+1)&((set d=2%d2%)&(goto a)))))))&((set /a d=%d%+1)&(goto d)))

答案 6 :(得分:0)

    @echo off
::PRIMES

set multiple2=1
set add=1
set counter=1
color f0
set /p range=Computer primes 0-?:
set /a limit=(range/2)+1
set ut=3
mkdir prime0-%range%
cd prime0-%range%
echo >>2
:opipe
echo >>%ut%
set /a ut=ut+2
if %ut% GEQ %range% goto next
goto opipe

:next
set /a multiple2=multiple2+2
if %multiple2% GEQ %limit% goto end
set /a add=add+2
set /a multiple=multiple2



:process
set /a multiple=multiple+add
del %multiple%
if %multiple% GEQ %range% goto next
goto process

:end
CD ..
echo 2 >>ALLprime0-%range%.txt

:offx
set /a counter=counter+2
if exist prime0-%range%\%counter% echo %counter% >>ALLprime0-%range%.txt
if %counter% GEQ %range% goto down
goto offx
:down 


echo Computation Succesful
pause
exit

::RMDIR /S /Q prime0-%range%

答案 7 :(得分:0)

请原谅我打败一匹死马。这是一种完全不同的方法来生成纯批次的素数,这种方法超过了我发现的其他所有素数。

它基于保持我们正在检查的窗口周围的多个先前找到的素数的列表。列表中未找到的数字是素数。为了保持列表,我使用@ composite = next_increment形式的环境变量。它使用单个循环,比其他算法中使用的嵌套双循环更快,速度更慢。不幸的是,需要一个FOR和一个辅助的subtrputine来克服在环境中重复键的不可能性,因为有时不同的素数会发生冲突。

顺便说一句,这个想法来自Knuth的TAOCP第3卷第617页。

var fs = require('fs'),
    path = require('path'),
    builtEdge = path.resolve(__dirname, '../build/Release/' + (process.env.EDGE_USE_CORECLR || !fs.existsSync(path.resolve(__dirname, '../build/Release/edge_nativeclr.node')) ? 'edge_coreclr.node' : 'edge_nativeclr.node')),
    edge;