中国DOS联盟论坛

中国DOS联盟

-- 联合DOS 推动DOS 发展DOS --

联盟域名:www.cn-dos.net  论坛域名:www.cn-dos.net/forum
DOS,代表着自由开放与发展,我们努力起来,学习FreeDOS和Linux的自由开放与GNU精神,共同创造和发展美好的自由与GNU GPL世界吧!

游客:  注册 | 登录 | 命令行 | 会员 | 搜索 | 上传 | 帮助 »
« [1] [2] [3] »
作者:
标题: [已结]排列组合 上一主题 | 下一主题
pusofalse
银牌会员




积分 1604
发帖 646
注册 2008-4-13
状态 离线
『楼 主』:  [已结]排列组合

随便给出一组字串 比如 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 ]

   此帖被 +2 点积分    点击查看详情   
评分人:【 zzz19760225 分数: +2  时间:2017-11-30 13:27




心绪平和,眼藏静谧,无比安稳的火... Purification of soul...Just a false...^_^
2008-6-29 05:35
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
pusofalse
银牌会员




积分 1604
发帖 646
注册 2008-4-13
状态 离线
『第 2 楼』:  这是我的代码

忙活了一个早晨,结果却发现重大的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 ]



心绪平和,眼藏静谧,无比安稳的火... Purification of soul...Just a false...^_^
2008-6-29 10:22
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
bat-zw
金牌会员

永远的学习者


积分 3105
发帖 1276
注册 2008-3-8
状态 离线
『第 3 楼』:  

不知道这样合要求不:
@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




批处理之家新域名:www.bathome.net
2008-6-29 11:04
查看资料  发送邮件  发短消息 网志  OICQ (841615149)  编辑帖子  回复  引用回复
pusofalse
银牌会员




积分 1604
发帖 646
注册 2008-4-13
状态 离线
『第 4 楼』:  

ZW前辈给出的代码也是有BUG的。。。 只能排列四个字符的组合 如果多出几个 只保留前面四个。。。 如果少了,会出现以零为除数的错误。。。
随机给出的字串,字串数量未知。。。



心绪平和,眼藏静谧,无比安稳的火... Purification of soul...Just a false...^_^
2008-6-29 11:07
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
bat-zw
金牌会员

永远的学习者


积分 3105
发帖 1276
注册 2008-3-8
状态 离线
『第 5 楼』:  



  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 ]

   此帖被 +8 点积分        点击查看详情   
评分人:【 pusofalse 分数: +8  时间:2008-6-29 11:34




批处理之家新域名:www.bathome.net
2008-6-29 11:29
查看资料  发送邮件  发短消息 网志  OICQ (841615149)  编辑帖子  回复  引用回复
pusofalse
银牌会员




积分 1604
发帖 646
注册 2008-4-13
状态 离线
『第 6 楼』:  

真是太感谢了! 学习中~



心绪平和,眼藏静谧,无比安稳的火... Purification of soul...Just a false...^_^
2008-6-29 11:35
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
bat-zw
金牌会员

永远的学习者


积分 3105
发帖 1276
注册 2008-3-8
状态 离线
『第 7 楼』:  



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

这样的方法当字符数到6位以上将会慢得吓人!,还是要需求别的方法了。



批处理之家新域名:www.bathome.net
2008-6-29 11:37
查看资料  发送邮件  发短消息 网志  OICQ (841615149)  编辑帖子  回复  引用回复
pusofalse
银牌会员




积分 1604
发帖 646
注册 2008-4-13
状态 离线
『第 8 楼』:  

嗯 试过了,6位以下还好。。。另外,还有一个bug 输入类似b e e n 这样的其中有两个相同字符的字串时会出错



心绪平和,眼藏静谧,无比安稳的火... Purification of soul...Just a false...^_^
2008-6-29 11:46
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
HAT
版主





积分 9023
发帖 5017
注册 2007-5-31
状态 离线
『第 9 楼』:  

以前学习《算法设计》的时候写过这样的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();
}




2008-6-29 11:52
查看资料  发短消息 网志   编辑帖子  回复  引用回复
bat-zw
金牌会员

永远的学习者


积分 3105
发帖 1276
注册 2008-3-8
状态 离线
『第 10 楼』:  

相同的字符好处理的:
在批处理中加入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 ]



批处理之家新域名:www.bathome.net
2008-6-29 11:52
查看资料  发送邮件  发短消息 网志  OICQ (841615149)  编辑帖子  回复  引用回复
plp626
银牌会员

钻石会员


积分 2278
发帖 1020
注册 2007-11-19
状态 离线
『第 11 楼』:  


@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位的代码类似

   此帖被 +2 点积分    点击查看详情   
评分人:【 xeibobin 分数: +2  时间:2009-9-20 06:51




山外有山,人外有人;低调做人,努力做事。

进入网盘(各种工具)~~ 空间~~cmd学习
2008-6-29 13:37
查看资料  发短消息 网志   编辑帖子  回复  引用回复
bat-zw
金牌会员

永远的学习者


积分 3105
发帖 1276
注册 2008-3-8
状态 离线
『第 12 楼』:  

终于提高了一点点效率,本机测试排列六位数将近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




批处理之家新域名:www.bathome.net
2008-6-29 13:47
查看资料  发送邮件  发短消息 网志  OICQ (841615149)  编辑帖子  回复  引用回复
plp626
银牌会员

钻石会员


积分 2278
发帖 1020
注册 2007-11-19
状态 离线
『第 13 楼』:  

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




山外有山,人外有人;低调做人,努力做事。

进入网盘(各种工具)~~ 空间~~cmd学习
2008-6-29 14:07
查看资料  发短消息 网志   编辑帖子  回复  引用回复
bat-zw
金牌会员

永远的学习者


积分 3105
发帖 1276
注册 2008-3-8
状态 离线
『第 14 楼』:  



  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 ...

方法是好啊,很快,但请搞清楚楼主的题意:“字符数不定”。



批处理之家新域名:www.bathome.net
2008-6-29 16:33
查看资料  发送邮件  发短消息 网志  OICQ (841615149)  编辑帖子  回复  引用回复
slore
铂金会员





积分 5212
发帖 2478
注册 2007-2-8
状态 离线
『第 15 楼』:  

根据n生成一个n重套嵌的bat然后调用=。=


bat貌似用参数可以实现“递归”。。。不过没有实践这个。。。脑细胞。。。

   此帖被 +11 点积分        点击查看详情   
评分人:【 pusofalse 分数: +11  时间:2008-12-18 12:39




S smile 微笑,L love 爱,O optimism 乐观,R relax 放松,E enthusiasm 热情...Slore
2008-6-29 17:19
查看资料  发短消息 网志   编辑帖子  回复  引用回复
« [1] [2] [3] »
请注意:您目前尚未注册或登录,请您注册登录以使用论坛的各项功能,例如发表和回复帖子等。


可打印版本 | 推荐给朋友 | 订阅主题 | 收藏主题



论坛跳转: