[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖
本帖最后由 523066680 于 2021-5-5 17:22 编辑

所以楼主说的是排列还是组合?没有说明组合的字符个数,应该是排列吧?
通过进制转换原理获得排列的模板,参考自《Higher-Order Perl》

TOP

本帖最后由 523066680 于 2021-5-6 09:58 编辑

回复 4# minase


    所以你要深度搜索解元素排列的非递归版本。递归转非递归,用堆栈呗。
建议改一下标题:批处理如何求排列组合(非递归)

    非递归的两个算法其他链接里面已经有了,只不过不是深度搜索,是其他算法。

TOP

非递归版

本帖最后由 523066680 于 2021-5-6 10:18 编辑
  1. my @elements = qw/a b c d e f g/;
  2. permute( [@elements], [] );
  3. sub permute
  4. {
  5.     my ( $elements ) = @_;
  6.     my @stk_ele = ( $elements );
  7.     my @stk_tmp= ( [] );
  8.     while ( $#stk_ele >= 0 )
  9.     {
  10.         my $ele = pop @stk_ele;
  11.         my $tmp = pop @stk_tmp;
  12.         printf "%s\n", join(",", @$tmp ) if $#$ele < 0;
  13.         for my $id ( 0 .. $#$ele )
  14.         {
  15.             push @stk_ele, [ @{$ele}[0..$id-1, $id+1..$#$ele] ];
  16.             push @stk_tmp, [ @$tmp, $ele->[$id] ];
  17.         }
  18.     }
  19. }
复制代码
堆栈版的来了。
虽然花了些时间,不过做出来发现蛮有趣的
因为是先把状态 push 到栈中,通过循环逐层解出,所以得出的结果是反向的,d c b a -> d c a b -> .... -> a b c d。

本机测试对比:
10个元素排列,去掉输出,递归版 12.3秒,非递归版 14.2秒

递归代码
  1. my @elements = qw/a b c d e f g h i j/;
  2. permute( [@elements], [] );
  3. sub permute {
  4.     my ($ele, $tmp ) = @_;
  5.     #printf "%s\n", join(",", @$tmp) unless ( @$ele );
  6.     for my $i ( 0 .. $#$ele ) {
  7.         permute( [@{$ele}[0..$i-1, $i+1..$#$ele]], [@$tmp, $ele->[$i]] );
  8.     }
  9. }
复制代码
也许换编译型语言耗时结果会不一样,懒得写了。

TOP

返回列表