バッチ ファイルを使用して小さなプロジェクトに取り組んでいましたが、問題が発生しました。私の知る限り、特定の変数が素数であるかどうかを確認する方法はありません。間違っている場合は、その方法を教えてください。そうでない場合は、回避策を考えてもらえますか?使用できます(数値がtxtファイルの素数のリストにある数値と等しいかどうかを確認するなど)。ありがとうございます^^
9 に答える
素数のテキスト ファイルが 1 行に 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
テストは実際には 2 つの部分に分割され、その 2 つ目は実際には新しい CMD インスタンスで実行されます。2 番目の部分は、実際にはスクリプトの先頭に表示されます。これは、パフォーマンス上の理由から行われます。これは、バッチ スクリプトを終了せずに 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!
最後に、念のために、次の素数 >= または <= 指定された数をリストするバリエーションを書きました。
::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
これらのスクリプトはすべて、私にはひどく(そして不必要に)大きく見えます。
これを行う簡単な方法は、を使用することです...私が探している用語は、モジュロ式またはモジュラス式のいずれかであると思います(モジュロは複数形またはモジュラスだと思います)。
@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かどうかをチェックします。
この方法は少し遅いですが、最短のコードです。2で割ったときに数値に余りがあるかどうかをチェックif
するループの前に別のステートメントを置くことで、少し短くすることができます。for
それが役に立てば幸い。
もう 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
素数 (1 行に各数値) を含むテキスト ファイルがあると仮定すると、次のようにすることができます。
@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!
。
@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%
次のスクリプトは素数性テストを実行しません。むしろ、特定の境界 (この特定のケースではハードコードされた 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
ここから撮影...