2016-01-25 27 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

謝謝,多數民衆贊成有點什麼,我試圖用我寫的代碼 - 首先產生正確的模式。我會看看維基 –