Board logo

标题: [文本处理] 【已解决】BAT或VBS:如何将七个位置进行全组合 [打印本页]

作者: 思想之翼    时间: 2015-11-17 13:15     标题: 【已解决】BAT或VBS:如何将七个位置进行全组合

本帖最后由 思想之翼 于 2015-11-18 11:04 编辑
  1. @echo off&setlocal enabledelayedexpansion
  2. for %%a in (0 1 2 3 4 5 6) do (
  3.     for %%b in (0 1 2 3 4 5 6) do (
  4.         for %%c in (0 1 2 3 4 5 6) do (
  5.             for %%d in (0 1 2 3 4 5 6) do (
  6.                 for %%e in (0 1 2 3 4 5 6) do (
  7.                     for %%f in (0 1 2 3 4 5 6) do (
  8.                         for %%g in (0 1 2 3 4 5 6) do (
  9.                             set var=%%a%%b%%c%%d%%e%%f%%g
  10.                             if not defined !var! (set !var!=m & echo !var!)               
  11.                         )
  12.                      )               
  13.                  )
  14.             )
  15.         )
  16.     )
  17. )
  18. pause>nul
复制代码
上述代码,将0123456这七个数据全组合,即第一位至第七位都选择七个数据 0 1 2 3 4 5 6

现在需要按位置进行全组合:
比如有数据1230401(数字有重复)
第一位可以选择七个数据:1、2、3、0、4、0、1
第一位如果选择了1,那么第二位只能在余下的六个数据 2、3、0、4、0、1中选择
第一位如果选择了1,第二位选择了2,那么第三位只能在余下的五个数据 3、0、4、0、1中选择
......
这样将1230401按位置进行全组合,有7*6*5*4*3*2*1=5040种可能。

现在如果文本中有数据:
0987664
1234555
6570030
每行数据都按位置进行全组合,分别得到一组5040个数据。将这3组数据合并写入新建的文本,这样的代码如何写?恳望得到帮助。
作者: ads350668398    时间: 2015-11-17 14:38

@echo off&setlocal enabledelayedexpansion&title

set L1=01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
for /d %%a in (%l1%) do (
  for /d %%b in (%l1%) do (
    if %%b GTR %%a (
      for /d %%c in (%l1%) do (
        if %%c GTR %%b (
          for /d %%d in (%l1%) do (
            if %%d GTR %%c (
              for /d %%e in (%l1%) do (
                if %%e GTR %%d (
                  for /d %%f in (%l1%) do (
                    if %%f GTR %%e (
                     
                          echo %%a %%b %%c %%d %%e %%f >>500.txt
                        )
                      )
                    )
                  )
                )
              )
            )
          )
        )
      )
    )
  )


你要的是不是这个#024 转
作者: 思想之翼    时间: 2015-11-17 16:55

本帖最后由 思想之翼 于 2015-11-17 17:46 编辑

回复 2# ads350668398

感谢您。但不符合我的思路。
作者: aa77dd@163.com    时间: 2015-11-17 20:33

  1. @echo off
  2. >outfile.txt cd.
  3. set "dic=a b c d e f g "
  4. set "alphabet=%dic: =%"
  5. call :proc "%dic%" > ttt
  6. for %%t in (
  7. 0987664
  8. 1234555
  9. 6570030
  10. ) do (
  11.     clip < ttt
  12.     setlocal enabledelayedexpansion
  13.     set "rep="
  14.     for /L %%i in (0 1 6) do (
  15.         set "str=%%t"
  16.         set "rep=!rep!.replace(/!alphabet:~%%i,1!/g,'!str:~%%i,1!')"
  17.     )
  18.     mshta.exe "javascript:s=clipboardData.getData('text')!rep!;fso=new ActiveXObject("Scripting.FileSystemObject");f=fso.OpenTextFile("tempfile",2,true);f.Write(s);f.Close();close();"
  19.     copy outfile.txt /b + tempfile /b outfile.txt /b
  20. )
  21. pause
  22. exit
  23. :proc
  24. (
  25.     if "%~1"=="" echo;%~2& exit /b
  26.     for %%i in (%~1) do (
  27.         setlocal enabledelayedexpansion
  28.         set oo=%~2%%i
  29.         set dic=%~1
  30.         call :proc "!dic:%%i =!" "!oo!"
  31.         endlocal
  32.     )
  33.     exit /b
  34. )
复制代码

作者: yiwuyun    时间: 2015-11-17 21:40

  1. if ($true){}# == ($true){}# goto ___yiwuyun
  2. <#BeginBatOperation#
  3. :___yiwuyun
  4. @echo off&setlocal&cls
  5. (echo $yiwuyun_fileName="%~f0"&echo $strPath="%~dp0"&type "%~f0")|powershell -command -
  6. exit/b 0
  7. #EndBatOperation#>
  8. <#StartPowerShell#>
  9. Function OutString{
  10.   param($Array)
  11. $x=0;
  12. for($i=0;$i -lt 7;$i++){
  13.   for($j=0;$j -lt 7;$j++){
  14.     if($i -eq $j){
  15.      continue;
  16.     }else{
  17.       for($k=0;$k -lt 7;$k++){
  18.         if($i -eq $k -or $j -eq $k){
  19.           continue;
  20.         }else{
  21.           for($l=0;$l -lt 7;$l++){
  22.             if($i -eq $l -or $j -eq $l -or $k -eq $l){
  23.               continue;
  24.             }else{
  25.               for($m=0;$m -lt 7;$m++){
  26.                 if($i -eq $m -or $j -eq $m -or $k -eq $m -or $l -eq $m){
  27.                   continue;
  28.                 }else{
  29.                   for($n=0;$n -lt 7;$n++){
  30.                     if($i -eq $n -or $j -eq $n -or $k -eq $n -or $l -eq $n -or $m -eq $n){
  31.                       continue;
  32.                     }else{
  33.                        for($o=0;$o -lt 7;$o++){
  34.                          if($i -eq $o -or $j -eq $o -or $k -eq $o -or $l -eq $o -or  $m -eq $o -or $n -eq $o){
  35.                            continue;
  36.                          }else{
  37.                            $x++;
  38.                            "$x`:$($Array[$i])$($Array[$j])$($Array[$k])$($Array[$l])$($Array[$m])$($Array[$n])$($Array[$o])";
  39.                          }
  40.                        }
  41.                     }
  42.                   }
  43.                 }
  44.               }
  45.             }
  46.           }
  47.         }
  48.       }  
  49.     }
  50.   }
  51. }
  52. }
  53. gc 1.txt|%{OutString -Array $_;}
  54. <#EndPowerShell#>
复制代码

作者: 思想之翼    时间: 2015-11-17 22:03

回复 4# aa77dd@163.com


    感谢您的帮助!测试了一下,结果正确。
    代码若能批量读取文本数据,就臻于完美了。比如:
    批量读取待组合的文本在D:/数据1/内,名称分别是0001.txt   0002.txt    0003.txt......0210.txt(文本内数据竖排,每行一数据)
   批量组合后的文本写入D:/数据2/内,名称分别是0001.txt   0002.txt    0003.txt......0210.txt
作者: aa77dd@163.com    时间: 2015-11-17 22:42

回复 6# 思想之翼
由于用到了剪贴板, 所以运行期间不要让剪贴板内容变化
  1. @echo off
  2. set "dic=a b c d e f g "
  3. set "alp=%dic: =%"
  4. call :proc "%dic%" > ttt
  5. clip < ttt
  6. setlocal enabledelayedexpansion
  7. for /L %%i in (10001 1 10210) do (
  8.     set "fn=%%i"
  9.     > D:\数据2\!fn:~-4!.txt cd.
  10.     for /f %%t in (D:\数据1\!fn:~-4!.txt) do (
  11.         set "str=%%t"
  12.         set "rep="
  13.         for /L %%i in (0 1 6) do set "rep=!rep!.replace(/!alp:~%%i,1!/g,'!str:~%%i,1!')"
  14.         mshta.exe "javascript:s=clipboardData.getData('text')!rep!;fso=new ActiveXObject("Scripting.FileSystemObject");f=fso.OpenTextFile("tempfile",2,true);f.Write(s);f.Close();close();"
  15.         copy D:\数据2\!fn:~-4!.txt /b + tempfile /b D:\数据2\!fn:~-4!.txt /b
  16.     )
  17. )
  18. pause
  19. exit
  20. :proc
  21. (
  22.     if "%~1"=="" echo;%~2& exit /b
  23.     for %%i in (%~1) do (
  24.         setlocal enabledelayedexpansion
  25.         set oo=%~2%%i
  26.         set dic=%~1
  27.         call :proc "!dic:%%i =!" "!oo!"
  28.         endlocal
  29.     )
  30.     exit /b
  31. )
复制代码

作者: 思想之翼    时间: 2015-11-17 23:05

本帖最后由 思想之翼 于 2015-11-18 01:48 编辑

回复 7# aa77dd@163.com

感谢!
数据多时,出现“已达到最大setlocal递归层”。
作者: CrLf    时间: 2015-11-18 00:55

绝不告诉你们有这个经典算法:
http://www.bathome.net/redirect. ... 11959&pid=76175
作者: terse    时间: 2015-11-18 01:57

  1. @echo off&setlocal enabledelayedexpansion
  2. set /a "i=1,n=6"
  3. for /l %%i in (0,1,%n%) do (
  4.     set /a "i*=%%i+1,#%%i=%%i+1"
  5.     set "J!#%%i!=!i!"
  6. )
  7. set /ai-=1
  8. pushd "d:\数据1\"
  9. for /f "delims=" %%a in ('dir /a-d /b "*.txt"') do (
  10.     (for /f "delims=" %%b in (%%a) do (
  11.         set "s=s%%b"
  12.         for /l %%i in (0,1,%i%) do (
  13.             setlocal
  14.             set M=%%i
  15.             for /l %%j in (%n%,-1,1) do (
  16.                 set /a "i=M/J%%j,M=%%i%%J%%j"
  17.                 set /a "#%%j=#!i!,#!i!=!#%%j!"
  18.             )
  19.             for /l %%i in (%n%,-1,0) do for %%j in (!#%%i!) do set $=!$!!s:~%%j,1!
  20.             echo;!$!
  21.             endlocal
  22.         )
  23.     ))>"d:\数据2\%%a"
  24. )
  25. pause
复制代码

作者: WHY    时间: 2015-11-18 14:43

本帖最后由 WHY 于 2015-11-18 15:24 编辑

我贴个VBS
  1. Dim strSrcDir, strDstDir, fso, i, strFile, objFile, strLine, s
  2. strSrcDir = "D:\数据1"
  3. strDstDir = "D:\数据2"
  4. Set fso = CreateObject("Scripting.FileSystemObject")
  5. If Not fso.FolderExists(strDstDir) Then fso.CreateFolder(strDstDir)
  6. For i = 1 To 210
  7.     strFile = Right(i+10000, 4) & ".txt"
  8.     If fso.FileExists(strSrcDir & "\" & strFile) Then
  9.         Set objFile = fso.OpenTextFile(strSrcDir & "\" & strFile, 1)
  10.         While Not objFile.AtEndOfStream
  11.             strLine = Trim(objFile.ReadLine)
  12.             If strLine <> "" Then
  13.                 s = ""
  14.                 Call getFullArray(strLine, "")
  15.                 fso.OpenTextFile(strDstDir & "\" & strFile, 8, True).Write(s)
  16.             End If
  17.         Wend
  18.         objFile.Close : Set objFile = Nothing
  19.     End If
  20. Next
  21. Set fso = Nothing
  22. MsgBox "成功!"
  23. Sub getFullArray(ByRef s1, ByRef s2)
  24.     Dim j
  25.     For j = 1 To Len(s1)
  26.         Call getFullArray(Left(s1, j-1) & Mid(s1, j+1), s2 & Mid(s1, j, 1))
  27.     Next
  28.     If Len(s1) = 0 Then s = s + s2 + vbCrLf : Exit Sub
  29. End Sub
复制代码

作者: wankoilz    时间: 2015-11-18 16:05

练习awk!
  1. # & cls & (for /f "delims=" %%a in ('dir/b/s d:\数据1\*.txt') do @gawk -f %0 %%a) & pause & exit
  2. #求全排列使用的“插入法”
  3. #注意:split函数产生空值的问题
  4. #如:split("a,",arr,","),生成的arr有两个元素,第二个元素为空值
  5. {
  6. #显示进度
  7. print "processing "FILENAME" row "NR
  8. s=$0;perm=""
  9. for(i=1;i<=length(s);i++){
  10. split(perm,arr,",");perm=""
  11. #开始perm为空,得到的arr也为空,为避免for(j in arr)不执行,初始一个空值
  12. if(length(arr)==0){arr[1]=""}
  13. word=substr(s,i,1)
  14. for(j in arr){
  15. for(k=0;k<=length(arr[j]);k++){
  16. tmp=substr(arr[j],1,k)""word""substr(arr[j],k+1,length(arr[j])-k)
  17. perm=perm""tmp","
  18. }
  19. }
  20. #去掉最后的分隔符",",以免split函数产生空值
  21. perm=substr(perm,1,length(perm)-1)
  22. }
  23. #将逗号换成换行符
  24. gsub(/,/,"\n",perm)
  25. #获得当前处理的文件名
  26. split(FILENAME,path,"\\")
  27. print perm >> "d:\\数据2\\"path[length(path)]
  28. }
复制代码





欢迎光临 批处理之家 (http://bbs.bathome.net/) Powered by Discuz! 7.2