Board logo

标题: [已结]排列组合 [打印本页]

作者: pusofalse     时间: 2008-6-29 05:35    标题: [已结]排列组合

随便给出一组字串 比如 a b c
罗列出a b c 所有的排列组合 即是输出 如下

a b c
a c b
b a c
b c a
c a b
c b a


我用笨方法,三重for循环能得到如此的结果,但字符数量不一定。。。
如此。。。求教高人。。。希望能总结出一个高效实用的方法。。。

[ Last edited by pusofalse on 2008-12-28 at 03:32 ]
作者: pusofalse     时间: 2008-6-29 10:22    标题: 这是我的代码

忙活了一个早晨,结果却发现重大的BUG 就是只能三个字符时 才能排列出所有组合 多了或少了都会出错 只能3个 请教各位高人,有没有好的方法~
@echo off&setlocal enabledelayedexpansion
del ts.txt>nul 2>nul
set var=1 2 3
:1
if defined var5 set var=%var5%
for %%a in (%var%) do (
        set dx=%%a
        set/a mn+=1
        set !mn!=%%a
        call :lp
)

if defined had echo 完成&pause>nul&exit/b
for /l %%a in (%mn% -1 1) do set "var5=!var5!!%%a! "
set had=had
goto 1


:lp
set var1=!var:%dx%=!
for %%a in (%var1%) do (
        set "var3=!var3!%%a "
)
>>ts.txt echo %var3%%dx%
set "%var3%%dx%=abcd"
set var3=
[ Last edited by pusofalse on 2008-6-29 at 10:29 AM ]
作者: bat-zw     时间: 2008-6-29 11:04
不知道这样合要求不:
@echo off&setlocal enabledelayedexpansion
if exist temp.txt del /q temp.txt
:begin
set code=abcd&set str=&set n=4
:again
set /a a=%random%%%%n%
set a=!code:~%a%,1!
set code=!code:%a%=!
set str=%str%%a%
set /a n-=1
if "%str:~3%" equ "" goto again
if defined var for %%i in (%var%) do if "%%i" equ "%str%" goto begin
echo %str%>>temp.txt
set var=%var% %str%
set /a m+=1
if %m% lss 24 goto begin
sort temp.txt&del /q temp.txt
pause>nul

作者: pusofalse     时间: 2008-6-29 11:07
ZW前辈给出的代码也是有BUG的。。。 只能排列四个字符的组合 如果多出几个 只保留前面四个。。。 如果少了,会出现以零为除数的错误。。。
随机给出的字串,字串数量未知。。。
作者: bat-zw     时间: 2008-6-29 11:29


  Quote:
Originally posted by pusofalse at 2008-6-29 11:07:
ZW前辈给出的代码也是有BUG的。。。 只能排列四个字符的组合 如果多出几个 只保留前面四个。。。 如果少了,会出现以零为除数的错误。。。
随机给出的字串,字串数量未知。。。

字符数不定确实是个大麻烦,下面的代码基本可以实现了(自己觉得好繁杂):
@echo off&setlocal enabledelayedexpansion
if exist temp.txt del /q temp.txt
:enter
cls&set /p codes=请输入字符组(字符间请用空格格开):
if not defined codes goto enter
for %%i in (%codes%) do set /a m+=1
set /a num=1,x=m,y=m-1
:lp
set /a num*=m
set /a m-=1
if %m% neq 0 goto lp
:begin
set code=!codes: =!&set str=&set /a n=x
:again
set /a a=%random%%%%n%
set a=!code:~%a%,1!
set code=!code:%a%=!
set str=%str%%a%
set /a n-=1
if "!str:~%y%!" equ "" goto again
if exist temp.txt for /f "delims=" %%i in (temp.txt) do if "%%i" equ "%str%" goto begin
echo %str%>>temp.txt
set /a m+=1
if %m% lss %num% goto begin
cls&sort temp.txt&del /q temp.txt
pause>nul
[ Last edited by zw19750516 on 2008-6-29 at 12:04 PM ]
作者: pusofalse     时间: 2008-6-29 11:35
真是太感谢了! 学习中~
作者: bat-zw     时间: 2008-6-29 11:37


  Quote:
Originally posted by pusofalse at 2008-6-29 11:35:
真是太感谢了! 学习中~

这样的方法当字符数到6位以上将会慢得吓人!,还是要需求别的方法了。
作者: pusofalse     时间: 2008-6-29 11:46
嗯 试过了,6位以下还好。。。另外,还有一个bug 输入类似b e e n 这样的其中有两个相同字符的字串时会出错
作者: HAT     时间: 2008-6-29 11:52
以前学习《算法设计》的时候写过这样的C代码,是一个递归算法。
/*本程序在TC2.0下运行通过*/
/*Algorithm 5.7 PERMUTATIONS1*/
#include<stdio.h>
int P[7];
void print(int P[],int n)
{
        int i;
        printf("\n");
        for(i=1;i<=n;i++)
                printf("%d",P[i]);
        sleep(1);
}

void perm1(int m,int n)
{
        int j,t;
        if(m==n)
                print(P,n);
        else
                for(j=m;j<=n;j++)
                {
                        t=P[j];
                        P[j]=P[m];
                        P[m]=t;
                        perm1(m+1,n);
                        t=P[j];
                        P[j]=P[m];
                        P[m]=t;
                }
}

main()
{
        int j,n;
        clrscr();
        window(35,1,46,1);
        textbackground(4);
        textcolor(128);
        clrscr();
        printf("www.cndos.cn\n");
        printf("Please input the value of n:");
        scanf("%d",&n);
        for(j=1;j<=n;j++)
                P[j]=j;
        perm1(1,n);
        printf("\nPress any key to end.");
        getch();
}

作者: bat-zw     时间: 2008-6-29 11:52
相同的字符好处理的:
在批处理中加入for %%i in (%codes%) do set a=#%%i#&set b=!b! !a!,再做相应处理,具体的代码我就不写了,只是高位的效率问题好像用批处理是解决不了的,因为用我二楼的方法set var=%var% %str%是会受到字符总数限制的。

[ Last edited by zw19750516 on 2008-6-29 at 12:02 PM ]
作者: plp626     时间: 2008-6-29 13:37

@echo off&setlocal enabledelayedexpansion
set s1=a b c
for %%a in (!s1!) do (set s2=!s1:%%a=!
  for %%b in (!s2!) do (set s3=!s2:%%b=!
    for %%c in (!s3!) do (echo %%a%%b%%c
) ) )
pause
6位的代码类似
作者: bat-zw     时间: 2008-6-29 13:47
终于提高了一点点效率,本机测试排列六位数将近10分钟:
@echo off&setlocal enabledelayedexpansion
if exist pl.txt del /q pl.txt
:enter
cls&set /p codes=请输入三个以上的字符(字符应不相同并请用空格格开):
if not defined codes goto enter
for %%i in (%codes%) do set /a m+=1
if %m% lss 3 set m=0&goto enter
cls&echo 正在排列中,请稍候...
set /a num1=1,x=m,y=m-1
:lp
set /a num1*=m,m-=1
if %m% neq 0 goto lp
set /a num2=num1/6+1,sz=1
:begin
set code=%codes: =%&set str=&set n=%x%
:again
set /a a=%random%%%%n%,n-=1
set a=!code:~%a%,1!
set str=%str%%a%&set code=!code:%a%=!
if "!str:~%y%!" equ "" goto again
for /l %%a in (1,1,%sz%) do (
    for %%i in (!var%%a!) do (
        if "%%i" equ "%str%" goto begin

   )
)
echo %str%>>temp.txt
set var%sz%=!var%sz%! %str%
set /a m+=1,z+=1
if %z% equ 6 set /a sz+=1,z=0
if %m% neq %num1% goto begin
sort temp.txt>pl.txt&del /q temp.txt&start pl.txt

作者: plp626     时间: 2008-6-29 14:07
7位用时2.28秒
timediff.bat 可在论坛p函数库里找到(用于计算两个时间点的差值)
@echo off&setlocal enabledelayedexpansion
set s1=a b c e d f g
set t=%time%
for %%a in (!s1!)do (set s2=!s1:%%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 s5=!s4:%%d=!
        for %%e in (!s5!)do (set s6=!s5:%%e=!
          for %%f in (!s6!)do (set s7=!s6:%%f=!
            for %%g in (!s7!)do (echo %%a%%b%%c%%d%%e%%f%%g
) ) ) ) ) ) )
call timediff.bat %t% %time% 0
pause

作者: bat-zw     时间: 2008-6-29 16:33


  Quote:
Originally posted by plp626 at 2008-6-29 14:07:
7位用时2.28秒
timediff.bat 可在论坛p函数库里找到(用于计算两个时间点的差值)
[code]@echo off&setlocal enabledelayedexpansion
set s1=a b c e d f g
set t=%time%
f ...

方法是好啊,很快,但请搞清楚楼主的题意:“字符数不定”。
作者: slore     时间: 2008-6-29 17:19
根据n生成一个n重套嵌的bat然后调用=。=


bat貌似用参数可以实现“递归”。。。不过没有实践这个。。。脑细胞。。。
作者: bat-zw     时间: 2008-6-29 19:18
脑袋想破了,还只能用替归法来算,以下代码在理论上适合10位内的排列,但不知怎么到了9位就出问题,郁闷啊:
@echo off&setlocal enabledelayedexpansion
if exist pl.txt del /q pl.txt
:set
cls&set /p s1=请输入字符组(字符间请用空格格开):
if not defined s1 goto set
for %%i in (%s1%) do set /a num+=1
for %%a in (%s1%) do (
    set s2=!s1:%%a=!
    set str=%%a
    if "!str:~%num%!" neq "" echo !str!>>pl.txt
    for %%b in (!s2!) do (
        set s3=!s2:%%b=!
        set str=%%a%%b
        if "!str:~%num%!" neq "" echo !str!>>pl.txt
        for %%c in (!s3!) do (
            set s4=!s3:%%c=!
            set str=%%a%%b%%c
            if "!str:~%num%!" neq "" echo !str!>>pl.txt
            for %%d in (!s4!) do (
                set s5=!s4:%%d=!
                set str=%%a%%b%%c%%d
                if "!str:~%num%!" neq "" echo !str!>>pl.txt
                for %%e in (!s5!) do (
                    set s6=!s5:%%e=!
                    set str=%%a%%b%%c%%d%%e
                    if "!str:~%num%!" neq "" echo !str!>>pl.txt
                    for %%f in (!s6!) do (
                        set s7=!s6:%%f=!
                        set str=%%a%%b%%c%%d%%e%%f
                        if "!str:~%num%!" neq "" echo !str!>>pl.txt
                        for %%g in (!s7!) do (
                            set s8=!s7:%%g=!
                            set str=%%a%%b%%c%%d%%e%%f%%g
                            if "!str:~%num%!" neq "" echo !str!>>pl.txt
                            for %%h in (!s8!) do (
                                set s9=!s9:%%h=!
                                set str=%%a%%b%%c%%d%%e%%f%%g%%h
                                if "!str:~%num%!" neq "" echo !str!>>pl.txt
                                for %%i in (!s9!) do (
                                    set s10=!s9:%%i=!
                                    set str=%%a%%b%%c%%d%%e%%f%%g%%h%%i
                                    if "!str:~%num%!" neq "" echo !str!>>pl.txt
                                    for %%j in (!s10!) do (
                                        set str=%%a%%b%%c%%d%%e%%f%%g%%h%%i%%j
                                        if "!str:~%num%!" neq "" echo !str!>>pl.txt
))))))))))
start pl.txt
[ Last edited by zw19750516 on 2008-6-29 at 07:28 PM ]
作者: plp626     时间: 2008-6-29 21:29
用递归 我想核心的代码不会超过3行可以搞定,谁来挑战下?
zw兄:
你这个代码生成了临时文件,也不叫递归,你的代码可以归为“另类”
作者: moniuming     时间: 2008-6-29 21:34
太多了麻烦,最主要是实现了就行了,想要排列更多的话,以此类推...
@echo off
setlocal enabledelayedexpansion
:begin
cls
set "n=0"
set /p s1=请输入8个以内的字符并用空格隔开:
for %%i in (%s1%) do (set /a n+=1)
if %n% gtr 8 goto :begin
for %%a in (!s1!) do (
   if "%n%"=="1" (echo %%a) else (set s2=!s1:%%a=!)
   for %%b in (!s2!) do (
      if "%n%"=="2" (echo %%a%%b) else (set s3=!s2:%%b=!)
      for %%c in (!s3!) do (
         if "%n%"=="3" (echo %%a%%b%%c) else (set s4=!s3:%%c=!)
         for %%d in (!s4!) do (
            if "%n%"=="4" (echo %%a%%b%%c%%d) else (set s5=!s4:%%d=!)
            for %%e in (!s5!) do (
               if "%n%"=="5" (echo %%a%%b%%c%%d%%e) else (set s6=!s5:%%e=!)
               for %%f in (!s6!) do (
                  if "%n%"=="6" (echo %%a%%b%%c%%d%%e%%f) else (set s7=!s6:%%f=!)
                  for %%g in (!s7!) do (
                     if "%n%"=="7" (echo %%a%%b%%c%%d%%e%%f%%g) else (set s8=!s7:%%g=!)
                     for %%h in (!s8!) do (
                        echo %%a%%b%%c%%d%%e%%f%%g%%h
))))))))
pause&goto :begin

作者: pusofalse     时间: 2008-6-29 21:35
我想这道题如果攻透了 会有很大用处的。。。
作者: HAT     时间: 2008-6-30 00:18
什么用处?生成暴力破解用的密码字典?
作者: pusofalse     时间: 2008-6-30 01:05
不只是暴力破解。。。总之就是与解码有关了。。。
作者: moniuming     时间: 2008-6-30 14:59
如果是猜测密码的话,把18楼的代码改成以下的也许更合适些吧
@echo off
setlocal enabledelayedexpansion
:begin
cls
for /l %%a in (1 1 10) do (set "s%%a=")
set "n="&set "var="&set "m="&set "count="
set /p var=请输入10个以内的字符(用不用空格隔开无所谓):
:more_
set "s1=!s1!!var:~,1! "
if not "!var:~1!"=="" set var=!var:~1!&goto :more_
for %%i in (%s1%) do (set /a m+=1)
if %m% gtr 10 (echo.&echo ...输入错误...&echo.&pause&goto :begin)
set /p n=请输入要组合的字符的数量(默认为全部):
set "t=%time%"
if "%n%"=="" set "n=%m%"
for %%a in (!s1!) do (
   if "%n%"=="1" (set /a count+=1&echo %%a) else (set s2=!s1:%%a=!)
   for %%b in (!s2!) do (
      if "%n%"=="2" (set /a count+=1&echo %%a%%b) else (set s3=!s2:%%b=!)
      for %%c in (!s3!) do (
         if "%n%"=="3" (set /a count+=1&echo %%a%%b%%c) else (set s4=!s3:%%c=!)
         for %%d in (!s4!) do (
            if "%n%"=="4" (set /a count+=1&echo %%a%%b%%c%%d) else (set s5=!s4:%%d=!)
            for %%e in (!s5!) do (
               if "%n%"=="5" (set /a count+=1&echo %%a%%b%%c%%d%%e) else (set s6=!s5:%%e=!)
               for %%f in (!s6!) do (
                  if "%n%"=="6" (set /a count+=1&echo %%a%%b%%c%%d%%e%%f) else (set s7=!s6:%%f=!)
                  for %%g in (!s7!) do (
                     if "%n%"=="7" (set /a count+=1&echo %%a%%b%%c%%d%%e%%f%%g) else (set s8=!s7:%%g=!)
                     for %%h in (!s8!) do (
                        if "%n%"=="8" (set /a count+=1&echo %%a%%b%%c%%d%%e%%f%%g%%h) else (set s9=!s8:%%h=!)
                        for %%i in (!s9!) do (
                           if "%n%"=="9" (set /a count+=1&echo %%a%%b%%c%%d%%e%%f%%g%%h%%i) else (set s10=!s9:%%i=!)
                           for %%j in (!s10!) do (
                              set /a count+=1&echo %%a%%b%%c%%d%%e%%f%%g%%h%%i%%j
))))))))))
echo.&echo 一共有 %count% 种组合&echo.
echo %t%
echo %time%
echo.&pause&goto :begin

作者: WANKOILZ     时间: 2008-6-30 17:40
我用“插入法”,发现效率还不错,代码也简短:
@echo off&setlocal enabledelayedexpansion
set/p chr=请输入要排列的字母,以空格分开:
for %%i in (%chr%) do set a=%%i
set - %a%=ok&set chr=!chr:%a%=!
for %%i in (%chr%) do call :out %%i
for /f "delims=-= tokens=1" %%i in ('set -') do echo %%i
pause>nul

:out
for /f "delims=-= tokens=1" %%i in ('set -') do (
  set - %1%%i=ok
  for %%j in (%%i) do (
    for %%k in (%%i) do (set str=!str! %%k&if %%j==%%k set str=!str! %1)
    set -!str!=ok&set str=
  )
  set -%%i=
)

作者: moniuming     时间: 2008-6-30 18:51    标题: 回23楼

经测试当输入7个数的时候,23楼的代码花费了三十几秒,而22楼的只用了几秒,试试??
要上班了,明天再来看结果,哈哈
作者: WANKOILZ     时间: 2008-6-30 20:41
肯定,call得太多自然效率低,我的关键是不限制字符数目。
作者: clian76     时间: 2008-12-1 16:31
如果给出的字符有重复就出错了!如:abbcd   又如:12321
可以修改去掉这个BUG吗
作者: 523066680     时间: 2008-12-17 17:19
文、代码:523066680
blog:  http://hi.baidu.com/523066680
发表于:http://www.cn-dos.net/forum/viewthread.php?tid=41243&fpage=1&highlight=&page=2     27楼

先贴代码
@echo off&setlocal enabledelayedexpansion
title code by hi.baidu.com/523066680
errorcommand>list.x 2>nul
echo,允许字符串重复,字符数不定,空格什么的字符就别试了哈. &echo.
set /p str="输入将被枚举排列情况的字符串(形式如:abcd): "
call :fo "%str%" ""
echo,--------已将信息导入 list.x文件 请检查.
pause
exit

:fo
if %1=="" (echo,%~2 &echo,%~2>>list.x&goto :eof)
if not defined _%~1 (set _%~1=-1)
set str=%~1

:foa
  set /a _%~1+=1,foa=_%~1,fob=foa+1
  call :fo "!str:~0,%foa%!!str:~%fob%!" "%~2!str:~%foa%,1!"
  set str=%~1
  set /a foa=_%~1
if not "!str:~%foa%,-1!"=="" (goto :foa)
set "_%~1="
goto :eof
我来了,黑板报出完了,心情无比放松,看中这道题,"研究"了几天,有点结果了,分享下.
主要内容  1.谈谈前面楼的代码
          2.分享我在解题过程中学到的东西
首先谈谈楼上的内容
    以 plp626 提出的多重for最为快速,虽然只能对指定数量的字符,但是可以修改啊,
22楼修改的不错,我觉得能到10个字符就可以满足需求了,尤其是速度就像直接type答案一样快.
    但是作为一个学者,寻求更好的办法是有必要的.于是23楼的代码超短(Good!),且符合要求
虽然没来得及理解,暂时发现的问题是:
         当我输入6个字符时,结束的时候按Enter居然不退出,估计
         可能死循环了.又看了下,汗,请大家测试的时候在pause>nul后面加exit
    另外,输入字符数多运行时间长是很自然的事情,我觉得不用挑这个毛病.

本人认为23楼代码很短,精悍,值得学习下的.

下面先说说本人解题过程学到的东西:
[主要是想要讨论call 的参数递归,关于这道题 ,上次看到batman 有快速的解法,
我就不转载了  期待 batman 大哥 续帖
]

1.也想对plp626代码改进,玩了一下用%var% 代表 一条命令执行的方法,下面给出理解版:
  @echo off
  set fo="for %%1 in (a b c) do (for %%2 in (a b c) do ("
  set end="))"

  %fo:"=%
         echo %%1 %%2
  %end:"=%
  pause
  
感觉太好玩了,不够"自动化"对吧?ok 我们用for 来决定要用几重for ,曾试着重组那个多重For的思路,
不过变量跟符号太多了,实在搞不下去,停工,思路别浪费,做别的. 用这个思路实现:
              根据用户输入的符号,列出这些符号包括本身的所有组合
      这是个简单点的题目,例如输入 1 2 则输出 1 1 , 1 2 , 2 1 , 2 2  好处主要是允许输入字符数不定.
虽然不了解"密码字典",不过感觉上要做的话这个代码应该更适合(比如说密码是223456的时候).
代码如下:
@echo off &setlocal enabledelayedexpansion
title code by hi.baidu.com/523066680
set "fo=" &set "end=" &set "n=0"
set /p "str=输入字符,以空格隔开: "
for %%a in (%str%) do set /a n+=1

for /l %%x in (1,1,%n%) do (
   set fo="for %%%%x in (%str%) do (!fo!"
   set end="!end!)"
   set echo=!echo! %%%%x
)

%fo:"=%
           echo %echo%
%end:"=%
pause
2.call 参数 回归
实现这个,我觉得可能Call可以实现,记得call
返回的时候,接下来的东西都是原来的,会不会参数也是原来的?

[经过多次失败发现,call的参数可返回,甚至是多层的返回,但set建立的变量在整个过程中是统一的]

所以,不能期待set 的变量也能有"重叠的记忆功能" ,要么加上编号,但会很繁杂的.

-----------------以下内容谈论call 参数
废话说多了,开始探究call有多强大(call 参数返回 理解版):
@echo off
call :a 123
:a
  echo %1

  :b
   if %1==123 (call :a 456) else (goto :eof)
   echo %1
   pause
   exit
还算好理解吧? 来个多层的,玩转call:
@echo off
echo,call :fo "abcd"
call :fo "abcd"
pause
exit

:fo
  if %1=="" (echo,参数1已经没有字符了,返回call,接下一句 &goto :eof)
  set str=%~1

  :foa
   echo,call :fo "%str:~1%"
   call :fo "%str:~1%"

   echo 已返回,现参数1的值为 %~1
   goto :eof
::一定很郁闷对吧,后面一句echo 咋显示4次,奥妙尽在goto :eof 因为本身就是被call了多次啊.
越玩越有趣啊, 自己那个代码就不打算详细分析了,写这篇文章不是晕大家的,所以我也主要用中文描述,讲一些可能用的上的东西.

温馨提示:很多问题阻碍了我很久,而我最后一次理清所有思路,是在关上电脑的时候,可见:经常对着电脑不利于思考啊.
----------------末
本人知识及能力实在有限,感觉这样分层的call并分层的返回 应该就是前面楼说的 "递归" 了吧
希望有资料的人把相关资料分享下哈.   现在感觉像是进入了完全不知道的逻辑领域....

[ Last edited by 523066680 on 2008-12-19 at 10:41 ]
作者: 523066680     时间: 2008-12-18 10:36
我写的这么辛苦 到网吧发表还得花钱,怎能不顶起来?

要是没人鸟 我以后也懒得写了....

[ Last edited by 523066680 on 2008-12-18 at 11:06 ]
作者: wxcute     时间: 2008-12-18 11:51
有些时候还是留给人自由思考的空间好。思路仅作为讨论用,而且是写得越简单越好,如果写得过于详细,容易造成思维定势。

一点建议,请勿见怪。
作者: 523066680     时间: 2008-12-19 10:24
说的很好  有道理 , 我决定把 文章改下
只讨论我过程中学到的批处理技术
作者: clian76     时间: 2008-12-21 04:21
感谢这么多高手,非常完美!
作者: clian76     时间: 2008-12-21 04:36
不过现在又有新问题,如输入字符有重复,如:13543 。用楼上的代码可以完美的得到所有打乱顺序的组合。但如果这5个字符中如有重复的字符,那输出的结果中也就会有完全一样的多个字符串。
如例中 13543 会生成如下结果,每个组合都出现了两次, 有什么办法可让它生成的时候不重复多余的一样的字符串?
----------------------------------list.x----------------------------------------------
13543
13534
13453
13435
13354
13345
15343
............
13345
33541
33415
33451
35134
35143
35314
35341
35413
35431
34135
34153
34315
34351
34513
34531
-----------------------------------------------end------------------------------------------

[ Last edited by clian76 on 2008-12-21 at 04:37 ]
作者: HAT     时间: 2008-12-21 11:34    标题: Re 32楼

先删除输入字符串中的重复字符,再排列组合行不?
作者: terse     时间: 2008-12-21 17:53
无临时文件
@echo off&setlocal enabledelayedexpansion
set/p str=请输入字符:
:lp
if defined str (
   set num=!str:~,1!
   if not defined ..!num! (
      set /a n+=1
      set ..!num!=b
      set "_!n!=!str:~,1!"&set "str=!str:~1!"
      goto lp
      ) else (
      set "str=!str:~1!"
      goto lp
    ))
    call:next
    echo %mn% 个组合
    pause&exit
:next
set/a m+=1
   if %m% leq %n% for /l %%i in (1 1 %n%) do (
      for %%j in (%~1) do set .%%j=%%j
        if not defined .%%i call :next "%~1 %%i"
          for /l %%k in (1 1 %n%) do set .%%k=
        ) else (
          for /l %%l in (1 1 %n%) do set .%%l=
          for %%m in (%~1) do set/p=!_%%m!<nul
          echo.
          set/a mn+=1
         )
          set/a m-=1
在batman兄的代码上简化下  有临时文件
@echo off&setlocal enabledelayedexpansion
set/p str=请输入字符:
:lp
   set num=!str:~,1!
   if not defined .!num! (
      set str1=!str1!!num!
      set /a n+=1
      set .!num!=b
      set "_!n!=!str:~,1!"&set "str=!str:~1!"
      if defined str goto lp
      )else (
      set "str=!str:~1!"
      if defined str goto lp
    )
set/a n-=1
>b.bat echo @echo off^&setlocal enabledelayedexpansion
>>b.bat echo set "str=%str1%"
>>b.bat echo for /l %%%%i in (0 1 %n%) do set _%%%%i=^^!str:~%%%%i,1^^!^&set var0=^^!var0^^! %%%%i
for /l %%i in (0 1 %n%) do (
set/a m+=1
if !m! gtr %n% (
>>b.bat echo for %%%%%%i in (^^!var%%i^^!^) do echo !var!^^!_%%%%%%i^^!)else (
>>b.bat echo for %%%%%%i in (^^!var%%i^^!^) do ^(set "var!m!=^!var%%i:%%%%%%i=^!"
        set "var=!var!^!_%%%%%%i^!"
        set "k=!k!^)"
        ))
>>b.bat echo set/a t+=1
>>b.bat echo %k%
>>b.bat echo echo %%t%% 个组合
call "b.bat"
del "b.bat"
pause>nul
[ Last edited by terse on 2008-12-24 at 03:12 ]
作者: clian76     时间: 2008-12-23 13:49
测试了一下楼上的代码,还是没达到想要的要求。楼上的代码只是告诉共有多少种组合。但并没有排除已存在的重复组合。
我的办法是在生成了一个文件后用FINDSTR再自我查找一次,过滤掉重复的字符串,
只是麻烦点。希望高手整个简便的就好了。
最后再次谢谢高手们!都太厉害了!
作者: terse     时间: 2008-12-24 03:14


  Quote:
Originally posted by clian76 at 2008-12-23 13:49:
测试了一下楼上的代码,还是没达到想要的要求。楼上的代码只是告诉共有多少种组合。但并没有排除已存在的重复组合。
我的办法是在生成了一个 ...

重新修正一下
删除输入字符串中的重复字符后 再组合 不知符合要求否?
作者: 523066680     时间: 2009-12-13 10:23
修改过
@echo off&setlocal enabledelayedexpansion
call :func "0" "" "abcdef"
pause &exit
:func
set str=%~3
if "%str:~1%"=="" (set /a na=%~1+1
                   echo,%~2%str%
                   goto :eof)
set na=0
:loop
set /a nb=na+1
call :func "%na%" "%~2!str:~%na%,1!" "!str:~0,%na%!!str:~%nb%!"
set str=%~3
if not "!str:~%na%!"=="" goto :loop
set /a na=%~1+1