|
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 ]
|
心绪平和,眼藏静谧,无比安稳的火... 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 |
|
|
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
状态 离线
|
|
2008-6-29 11:29 |
|
|
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 |
|
|
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 |
|
|
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位的代码类似
|
山外有山,人外有人;低调做人,努力做事。
进入网盘(各种工具)~~ 空间~~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 |
|
|
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 |
|
|
slore
铂金会员
积分 5212
发帖 2478
注册 2007-2-8
状态 离线
|
『第
15 楼』:
根据n生成一个n重套嵌的bat然后调用=。=
bat貌似用参数可以实现“递归”。。。不过没有实践这个。。。脑细胞。。。
|
S smile 微笑,L love 爱,O optimism 乐观,R relax 放松,E enthusiasm 热情...Slore |
|
2008-6-29 17:19 |
|