0

私の友人から、ランダムな1と0の文字列を行列のように出力するプログラムを作成するように依頼されました。私は同意し、目的の出力を持つプログラムをバッチで作成することに成功しましたが、実行速度が遅く、より効率的にする方法があるかどうか疑問に思いました。

set count=0

:loopassign
if %count%==80 goto show
set/a count=%count%+1
set/a value=%random% %% 2
set number%count%=%value%
goto loopassign

:show
echo {             %number1%%number2%%number3%%number4%%number5%%number6%%number7%%number8%%number9%%number10%%number11%%number12%%number13%%number14%%number15%%number16%%number17%%number18%%number19%%number20%%number21%%number23%%number24%%number25%%number26%%number27%%number28%%number29%%number30%%number31%%number32%%number33%%number43%%number44%%number45%%number46%%number47%%number48%%number49%%number50%%number51%%number52%%number53%%number54%%number55%%number56%%number57%%number58%%number59%%number60%%number61%%number62%%number63%%number64%%number65%%number66%%number67%%number68%%number69%%number70%%number71%%number72%%number73%%number74%%number75%%number76%%number77%%number78%%number79%%number80% }
set count=0
goto loopassign
4

3 に答える 3

1

主に時間のかかる部分はgoto loopassign.
これは、FOR /L ループに置き換えることができます。

ラベルを検索する際にファイル全体をスキャンする必要がなくなるため、ループは goto よりも優れています。
また、for ブロック内のコードはキャッシュされ、一度だけ解析されるため、実行がはるかに高速になります。

1 文字に 80 個の変数を使用する代わりに 1 行の変数を使用するのは、保守性のためだけです。

@echo off
setlocal enableDelayedExpansion
set count=0

:loopassign
set "line="
for /L %%n in (1,1,80) do (
    set /a "value=!random! & 1"
    set "line=!line!!value!"
)

:show
echo {             !line! }
goto loopassign

より改善された速度バリアント

各ループで 1 文字ではなく 4 文字を生成する簡単なトリックを使用して、簡単に高速化できるため、1 行に必要なループは 20 回だけです。

for /L %%n in (1,1,20) do (
    set /a "n=!random! & 15,m=10000+(n&8)*125+(n&4)*25+(n&2)*5+(n & 1)"
    set "ln=!ln!!m:~-4!"
)

これは3倍速くなるようです

于 2013-02-12T20:01:43.127 に答える
1

速度テスト プログラムが大好きです。下の鉱山の方が速いと思います...

@echo off
setlocal EnableDelayedExpansion

rem Create a Decimal-to-Binary conversion table for values from 0 to 15
set dec=0
for %%n in (0000 0001 0010 0011 0100 0101 0110 0111
            1000 1001 1010 1011 1100 1101 1110 1111 ) do (
   set bin[!dec!]=%%n
   set /A dec+=1
)

rem Repeat the loop 5 times per line
set line=
for /L %%n in (1,1,5) do (
   rem Generate 4 groups of 4 bits per cycle
   set /A "G1=(n=!random!)&15, G2=(n>>=(G1&3)+1)&15, G3=(n>>=4)&15, G4=(n>>4)&15"
   for /F "tokens=1-4" %%a in ("!G1! !G2! !G3! !G4!") do (
      set line=!line!!bin[%%a]!!bin[%%b]!!bin[%%c]!!bin[%%d]!
   )
)
echo {             %line%}

アントニオ

編集: 80 桁の 2 進数の行の 5 つの固定位置でゼロを回避するために、式をわずかに変更しました。

于 2013-02-13T01:24:46.423 に答える
1

について学ぶべきです

  • FOR ループ:HELP FORコマンド プロンプトから入力します。特に、FOR /L オプションが必要です。

  • 遅延展開:HELP SETコマンド プロンプトから入力します。展開の遅延に関するセクションは、ヘルプの約半分にあります。

これは、2 つの FOR /L ループを使用するソリューションです。外側のループは、カウンターをインクリメントしないため、無限です。

@echo off
setlocal enableDelayedExpansion
for /l %%Z in (0 0 1) do (
  set "ln="
  for /l %%N in (1 1 80) do (
    set /a "n=!random! %% 2"
    set "ln=!ln!!n!"
  )
  echo {             !ln! }
)
exit /b
于 2013-02-12T20:16:50.193 に答える