2016-01-25 28 views
1

我有一个网格,其中我们可以表示为ABC的列和行可以表示为例如x,y,z类型。所有组合在柱状顺序

可能有多行都被归类为相同类型。这是不正确的列。

同一行的行不应该组合或“混合”。所有的组合都需要按照ABC的顺序,而不是CBA或其他任何组合。这是我想出的一个例子。

我需要下表的打印出每一个组合(columnal顺序):

 A B C 
    -------------- 
x | 10 20 30 
x | 11 21 31 

y | 40 50 60 
y | 41 51 61 

z | 70 80 90 

的输出需要是这样的(它没有输出模式,这只是参考):

(Pattern) (Result) 
Ax Bx Cx {10 20 30} {11 21 31} (notice no mix-combinations on same letter x) 
Ax Bx Cy {10 20 60} {10 20 61} {11 21 60} {11 21 61} 
Ax Bx Cz {10 20 90} {11 21 90} 
Ax By Cx {10 50 30} {10 51 30} {11 50 31} {11 51 31} 
Ax By Cy {10 50 60} {10 51 61} {11 50 60} {11 51 61} 
Ax By Cz {10 50 90} {10 51 90} {11 50 90} {11 51 90} 
Ax Bz Cx {10 80 30} {11 80 31} 
Ax Bz Cy {10 80 60} {10 80 61} {11 80 60} {11 80 61} 
Ax Bz Cz {10 80 90} {11 80 90} 


Ay Bx Cx {40 20 30} {40 21 31} {41 20 30} {41 21 31} 
Ay Bx Cy ... 
Ay Bx Cz ... 
Ay By Cx ... 
Ay By Cy ... 
Ay By Cz ... 
Ay Bz Cx ... 
Ay Bz Cy ... 
Ay Bz Cz ... 

Az Bx Cx ... 
Az Bx Cy ... 
Az Bx Cz ... 
Az By Cx ... 
Az By Cy ... 
Az By Cz ... 
Az Bz Cx ... 
Az Bz Cy ... 
Az Bz Cz {30 60 90} 

我有一些Tcl代码,我已经开始做这个,但它不是很好。它并不需要相同的x Y或Z的多行考虑,但这里是我走到这一步:

set dl {0 1 2} 
set op {x y z} 

set debug [open "debugloop.txt" "w"] 
set i 0 
set j 0 
set k 0 
set e 0 
set r 0 
set s 0 
set g yes 
while {$g} { 
    puts $debug A[lindex $op $i][lindex $dl $e]B[lindex $op $j][lindex $dl $r]C[lindex $op $k][lindex $dl $s] 
    incr s 
    if {$s > 2} { 
    puts $debug "" 
    incr r 
    set s 0 
    if {$r > 2} { 
     puts $debug "" 
     incr e 
     set r 0 
     if {$e > 2} { 
     puts $debug "" 
     incr k 
     set e 0 
     if {$k > 2} { 
      puts $debug "" 
      incr j 
      set k 0 
      if {$j > 2} { 
      puts $debug "" 
      incr i 
      set j 0 
      if {$i > 2} { 
       set g no 
      } 
      } 
     } 
     } 
    } 
    } 
} 

没有任何人有更好的方式来做到这一点不是一系列硬编码的嵌套循环?我有很多的麻烦,这

回答

1

有2个主要部分,您的问题:

  1. 生成所有的(模式)的组合
  2. 存储的方式,让您的数据查找每个组合的(结果)。

对于其中的第一个,您需要在您的示例中生成所有具有重复允许的模式值x,y,z的排列组合。在tcl wiki上有一些代码。

在你的情况下,顺序很重要,{x,y,z}与{z,y,x}不一样,所以算法需要考虑到这一点。下面是一些使用简单算法生成重复排列的代码,它使用了通过计算模数元素数来生成所有排列的想法。排列的数量增长很快,请看permCount的计算方法!

# Permutaions 
proc NextPerm {perm values} { 

    set result {} 
    set needIncr 1 
    foreach val $perm { 
     if { $needIncr == 1} { 
      set newVal [lindex $values [expr {[lsearch -exact $values $val] + 1}]] 
      if {$newVal != ""} { 
       # New value was found 
       lappend result $newVal 
       set needIncr 0 
      } else { 
       # No next value found so we need to carry 
       lappend result [lindex $values 0] 
      } 
     } else { 
      lappend result $val 
     } 
    } 

    return $result 
} 

set values {x y z} 
set perm {x x x} 

puts $perm 
set permCount [expr {[llength $perm] ** [llength $perm]}] 
for {set i 1} {$i < $permCount} {incr i} { 
    set perm [NextPerm $perm $values] 
    puts $perm 
} 

注意:我没有试图优化这段代码。

如果模式值永远不会改变,而不是自己生成它们,您可以使用在线资源,如this(如果您执行搜索,还有许多其他网站)生成值并将其硬编码到您的程序中。

对于2我会看看存储在一个数组或字典中的值与一个关键,可以让你拉回相关的值。

+0

谢谢,多数民众赞成有点什么,我试图用我写的代码 - 首先产生正确的模式。我会看看维基 –