批量质数

Cro*_*non 1 batch-file

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

dbe*_*ham 5

如果您有一个质数文本文件,每行 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
)
Run Code Online (Sandbox Code Playgroud)


更新

这是一个本机批处理脚本,可以测试批处理支持的任何有效整数(有符号的 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
Run Code Online (Sandbox Code Playgroud)

测试实际上分为两部分,其中第二部分实际上是在一个新的 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
Run Code Online (Sandbox Code Playgroud)

上面的输出如下所示:

                          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!
Run Code Online (Sandbox Code Playgroud)


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

::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!
Run Code Online (Sandbox Code Playgroud)

这是输出的用法演示:

D:\test>nextPrime 10000000
10000019

D:\test>nextPrime /l 10000000
9999991
Run Code Online (Sandbox Code Playgroud)