批处理之家's Archiver

youxi01 发表于 2008-1-3 23:19

批处理产生四个四位不重复的随机数

要求:
1、随机数的位数为4位(首位不能为0),且随机数由四个不重复的数字组成;
2、随机数之间不能重复

zhangxiaopeng 发表于 2008-4-3 23:30

管理员也不公布一下答案呀。。。。

随风 发表于 2008-4-4 00:28

[code]@echo off
set ci=4
:start
set /a w=%random%%%9+1,y=9
set "var=0 1 2 3 4 5 6 7 8 9"
call set "var=%%var:%w%=%%"
for /l %%a in (1 1 3) do call :loop
if not defined _%w% (
   set _%w%=a
   echo %w%
   set /a ci-=1
)
if %ci% neq 0 goto start
echo\&pause&exit
:loop
set /a n=%random%%%%y%+1
for /f "tokens=%n%" %%a in ("%var%") do set "m=%%a"
set /a "y-=1"
set "w=%w%%m%"
call set "var=%%var:%m%=%%"
goto :eof[/code]

zhangxiaopeng 发表于 2008-4-4 10:53

哇!昨天刚回复完,今天就有了,真不错。。不像一般的论坛。里面产生随机数那一行,w=%random%%%9+1,y=9 后面三个%能解释是什么意思么?

youxi01 发表于 2008-4-4 11:13

回复 4楼 的帖子

这个代码他自己解释是最清楚的,呵呵,旁人还是不说了/

youxi01 发表于 2008-4-4 11:13

回复 3楼 的帖子

兄的代码是不是人为的复杂化了?

随风 发表于 2008-4-4 12:54

回复 6楼 的帖子

你觉得是人为的复杂了?
我似乎精简不出来了。代码最主要的是想考虑效率问题,避免反复 goto

回 4 楼
set /a w=%random%%%9+1,y=9
可以看成
set /a w=%random%%%9+1
set /a y=9
set /a w=%random%%%9+1  %rqndom% 是个随机数 %% 代表取余操作。9+1 代表取的数底数为 1 范围是 9

小竹 发表于 2008-4-4 14:18

[code]@echo off
setlocal enabledelayedexpansion
set var=123456789
set /a h1=%random%%%9+1
set var=!var:%h1%=0!
for /l %%i in (9,-1,7) do (
        set /a temp=!random!%%%%i
        call set h%%i=%%var:~!temp!,1%%
        call set var=%%var:!h%%i!=%%
)
echo %h1%%h9%%h8%%h7%
pause
[/code]

随风 发表于 2008-4-4 14:46

思路很巧啊

youxi01 发表于 2008-4-4 14:47

回复 8楼 的帖子

似乎只产生一个随机数
对于多个随机数,没有进行重复性判断(尽管这种几率很小)

youxi01 发表于 2008-4-4 15:14

来一段“无赖”代码,通过for中循环值调整随机度。[code]@echo off
setlocal enabledelayedexpansion
set /a str=123456789
for /l %%i in (1 1 10) do (
     set /a num=!random! %% 9+1
     call set str=%%str:!num!=%%!num!
)
echo !str:~2,4!
pause[/code]

小竹 发表于 2008-4-4 16:39

回复 11楼 的帖子

首位不能为0,但其它位可以为0。

梦想种子 发表于 2008-4-4 20:41

来个思路一般的:[code]@echo off
:loop
setlocal enabledelayedexpansion
:num
set /a t=!random!%%10
if defined %t% goto num
set %t%=ok
set n=%n%%t%
if "%n:~3%" == "" goto num
if %n% lss 1000 (endlocal&goto loop)
echo %n%
pause[/code]再来个效率超低的:[code]@echo off
:loop
setlocal enabledelayedexpansion
for /l %%i in (0,1,9) do set +!random!=%%i
for /f "skip=6 delims=" %%j in ('set +^|sort') do (
set t=%%j
set a=!a!!t:~-1!
)
if !a! lss 1000 (endlocal&goto loop)
echo !a!
pause[/code]

sjzong 发表于 2009-4-25 15:38

我也试试

请问楼主:是产生一个四位数都不重复的数,还是产生四个四位数都不重复的数??
思路:随机取出该数的千、百、十、个位的数字,然后判断该数是否跟前面取的数重复;还要判断是否已经取满四个数[code]@echo off
setlocal enabledelayedexpansion
set str=0123456789
:main
cls
set var=
:a
set s1=!str:0=!
set/a num=%random%%%9
set num1=!s1:~%num%,1!
set s2=!str:%num1%=!
set/a num=%random%%%9
set num2=!s2:~%num%,1!
set s3=!s2:%num2%=!
set/a num=%random%%%8
set num3=!s3:~%num%,1!
set s4=!s3:%num3%=!
set/a num=%random%%%7
set num4=!s4:~%num%,1!
set num=!num1!!num2!!num3!!num4!
set/a n=0
for %%a in (!var!) do (
set/a n+=1
if %%a equ !num! goto :a
)
if !n!==4 (echo !var!&pause>nul&goto main) else (set var=!var! !num!&goto :a)[/code]

[[i] 本帖最后由 sjzong 于 2009-4-25 15:55 编辑 [/i]]

inittab 发表于 2009-4-25 17:36

我也来一个吧。能生成一批四位不重复的随机数:[code]@echo off&setlocal enabledelayedexpansion
::生成四位的随机数100个
for /l %%i in (1,1,100) do (set/a #%%i=!random!%%9000+1000)
::过滤掉有重复数字的随机数
for /l %%i in (0,1,100) do (
for /l %%j in (0,1,9) do (
set ss=!#%%i:%%j=!
if !ss! lss 100 (set "#%%i=")
)
)
for /f "tokens=2 delims=#=" %%i in ('set #') do echo %%i

pause[/code]

随风 发表于 2009-4-25 21:44

回复 15楼 的帖子

功力不错啊,学什么的。
赞!

defanive 发表于 2009-4-25 21:49

15L的代码强。。。

不过能保证100个数以内肯定能生成么。。。

sjzong 发表于 2009-4-26 05:17

回 15 楼的

15楼的思路的确很有新意!
但是我有两个疑问:
1、如果题目假设成求出全部四位不重复的四位数时,那循环次数是非常多了,速度就慢多了,因为1000~9999就有9000个,然后每一个再来删除重复字符(0~9共10),那就要运行9000*10次数!
       换成另一种思路:先取千位(千位为10个数字扣除0,共9个),再取百位(百位为10个数字扣除千位的数字,共9个),再取十位(十位为10个数字扣除千位、百位两个,共8个),最后取个位(个位为10个数字扣除千位、百位、十位三个,共7个),利用排列组合,列出所有的数需要运行9*9*8*7=4536次。
       那两种思路的效率高呢??? 希望楼主按你的思路写出可以列出四位不重复的四位数代码,然后跟下面代码对比一下,看看速度怎么样?
[code]@echo off
setlocal enabledelayedexpansion
set str=0 1 2 3 4 5 6 7 8 9
set s1=!str:0=!
for %%a in (!s1!) do (
set s2=!str:%%a=!
for %%b in (!s2!) do (
set s3=!s2:%%b=!
for %%c in (!s3!) do (
set s4=!s3:%%c=!
for %%d in (!s4!) do (
set/a num+=1
echo %%a%%b%%c%%d
))))
echo !num!
pause[/code]
2、题目所提出的数字要求是随机数,按照15楼的方法时就难免会出现重复的数,就是第一次取随机数1234,有可能也取1234,虽然这种概率很小的!但毕竟存在。

inittab 发表于 2009-4-26 16:59

如果按顺序排列。这个题目基本上没有难度了。(问题变成了:找出10000以内没有重复数字的四位数)

题目要求是, 生成四个随机的,没有重复数字的四位随机数

15的代码还存在相同数字的可能性。

有更好的改进代码,请跟进

[[i] 本帖最后由 inittab 于 2009-4-26 17:26 编辑 [/i]]

wangqi0077 发表于 2010-9-10 14:34

[code]@echo off
:start
set /a a=%random%%%10
set /a b=%random%%%10
set /a c=%random%%%10
set /a d=%random%%%10
echo %a%
echo %b%
echo %c%
echo %d%
if %a% neq 0 (
if %a% neq %b% (
   if %a% neq %b% (
      if %a% neq %c% (
         if %a% neq %d% (
            if %b% neq %c% (
               if %b% neq %d% (
                 if %c% neq %d% (echo %a%%b%%c%%d%) else goto start
                              ) else goto start
                           ) else goto start
                        ) else goto start
                     ) else goto start
                   ) else goto start
                ) else goto start
             ) else goto start
pause
goto start
pause[/code]水平有限..全用IF来弄的.
能问问高手.除中间的goto start 外,其他除了最后一个.中间的可以不要吗???自己都弄晕了.

[[i] 本帖最后由 wangqi0077 于 2010-9-10 14:53 编辑 [/i]]

wc726842270 发表于 2010-9-11 21:46

[code]@echo off
%random%
set a=%random%
if %a% gtr 999 goto 2
:2
if %a% lss 10000 (echo %a% >>a.txt) else goto 3
:3
call a.bat[/code]

wc726842270 发表于 2010-9-11 21:48

我将BAT文件保存为a.bat 了.忘说了

lvsehuaxue 发表于 2010-9-27 20:05

请高手判断是对还是错?

[code]@echo off
set /a m+=1
:loop
set /a n+=1
set /a v%n%=%random%%%9000+1000
call set m%n%=%%v%n%%%
if %n% lss 4 goto loop
if %m1% neq %m2% (if %m2% neq %m3% (if %m3% neq %m4% echo %m1% %m2% %m3% %m4%))
pause[/code]

lvsehuaxue 发表于 2010-9-27 20:09

23楼没说清楚

有的代码写出之后,我可以自己想办法验证。23楼的代码写出之后,我没法验证是对还是错(我找不出验证的办法),所以,请高手判断一下对错。再次感谢!

lvsehuaxue 发表于 2010-9-27 20:12

23楼代码发错了,改正如下

[code]@echo off
:loop
set /a n+=1
set /a v%n%=%random%%%9000+1000
call set m%n%=%%v%n%%%
if %n% lss 4 goto loop
if %m1% neq %m2% (if %m2% neq %m3% (if %m3% neq %m4% echo %m1% %m2% %m3% %m4%))
pause[/code]

523066680 发表于 2010-9-27 21:12

擦啊……都这么精简
粗也上了[code]@echo off
setlocal enabledelayedexpansion
set /a mi=0
:main
for /l %%a in (0,1,9) do (set arr[%%a]=%%a)
set /a i=0,num=%random% %% 9+1
set /a arr[%num%]=arr[9]
   :next
     set /a i+=1,rnd=%random% %% (10-i),last=9-i
     set /a rand=!arr[%rnd%]!,num=num*10+rand,arr[%rnd%]=arr[%last%]
   if %i% lss 3 goto :next
   if defined number[%num%] (goto :main) else (
       set /a number[%num%]=1,mi+=1
       echo %num%
   )
if %mi% lss 4 goto :main
pause[/code]

[[i] 本帖最后由 523066680 于 2010-9-28 15:08 编辑 [/i]]

netbenton 发表于 2010-9-27 21:44

炒冷饭呀~~~
我也来个,一次搞得一百个。
不够么!!自己把100改大点。。。
[code]@echo off&setlocal enabledelayedexpansion
for /l %%i in (0,1,9) do set ms=!ms!%%i

:lp
for /l %%i in (1,1,100) do (
  set ns=!ms!
  set n=9
  set/a v=!random!%%9+1
  for %%b in (!v!) do set s=!ns:~%%b,1!

  for /l %%a in (1,1,3) do (
    for %%b in ("!s:~-1!") do set ns=!ns:%%~b=!
    set /a v=!random!%%n,n-=1
    for %%b in (!v!) do set s=!s!!ns:~%%b,1!
  )
echo !s!
)
pause
goto :lp[/code]

523066680 发表于 2010-9-27 21:56

回复 27楼 的帖子

刚刚想了一下 , inittab 的剔除重复数字的应该是比较全面稳妥的做法
本顿的测试导出100个,偶尔是会出现重复的,
如果数字更大一些,重复的会多一些。

回忆到以前学概率的时候哎,0-9组成 4位数,每一位不重复,第一位不能为0
9*9*8*7=4536 种不同结果

[[i] 本帖最后由 523066680 于 2010-9-27 22:40 编辑 [/i]]

523066680 发表于 2010-9-27 22:37

我测了一下总数
15楼的代码找到漏洞:
筛选重复数字的部分:
[quote]
for /l %%j in (0,1,9) do (
set ss=!#%%i:%%j=!
if !ss! lss 100 (set "#%%i=")
)
[/quote]

这里,比如数字是1023 , 剔除1=023
而023<100 所以会被清理。 所以15楼的代码永远不会出现10开头的4位数

netbenton 发表于 2010-9-28 04:57

27楼回贴只看到第一个条件,

再来个满足两个条件的:(随机列出所有四位数,并满足一楼的两个条件要求)

[code]@echo off&setlocal enabledelayedexpansion
for /l %%i in (0,1,9) do set ms=!ms! %%i

set as=!ms: 0=!
(
for %%a in (!as!) do (
  set bs=!ms: %%a=!
  for %%b in (!bs!) do (
    set cs=!bs: %%b=!
    for %%c in (!cs!) do (
      set ds=!cs: %%c=!
      for %%d in (!ds!) do (
        echo;!random! %%a%%b%%c%%d
) ) ) )

)>nums.tmp
for /f "tokens=2" %%a in ('sort nums.tmp') do (echo;%%a)
pause[/code]

页: [1] 2

Powered by Discuz! Archiver 7.2  © 2001-2009 Comsenz Inc.