[問題] 關於重複組合的演算法問題

看板Prob_Solve (計算數學 Problem Solving)作者 (克里斯)時間16年前 (2008/12/09 17:58), 編輯推噓1(100)
留言1則, 1人參與, 最新討論串1/1
※ [本文轉錄自 C_and_CPP 看板] 作者: chrisdar (克里斯) 看板: C_and_CPP 標題: [問題] 關於重複組合的演算法問題 時間: Tue Dec 9 14:01:13 2008 關於重複組合的演算法問題 我想了一個演算法模仿next_permutation(疊代型), 我稱做 next_combination。 用法類似這樣 string ss("0011223344"); do{ cout << ss.substr(0,3) << endl; }while (next_combination(ss.begin(),ss.begin()+3,ss.end())); 舉例0011223344要取3個作組合 0011223344 ├─┤ → 1必須要向後找到一個大於他的與之交換 0021123344 ├───┤ 0031122344 ├─────┤ ↗0041122334 由於4找不到比他大的,則往 0041122334 / ├┼┼┤ →前推移一位, 04 跟 11 交換 ├┼┼┤ → 0110422334 0110223344 ╲ ├────┤→交換後需要rotate旋轉1次 ├─┤ ↘0110223344 0120123344 ├───┤ 0130122344 ├─────┤ ↗0140122334 由於4找不到比他大的,則往 0140122334 ╱ ├┼──┼┤ →前推移一位, 14 跟 22 交換 ├┼──┼┤ → 0220114334 0220113344 ╲ ├──┤→交換後需要rotate旋轉1次 ├───┤ ↘0220113344 0230112344 ├─────┤ ↗0240112334 由於4找不到比他大的,則往 0240112334  ╱ ├┼────┼┤ →前推移一位, 24 跟 33 交換 ├┼────┼┤ → 0330112244 0330112244 ╲ ├┤→交換後需要rotate旋轉1次 ├─────┤ ↘0330112244 0340112234 ├┼──────┼┤→原本要交換兩個因為到底了就只換一個 0440112233 ├┼┼──┼┼┤ ┐ ↗0440112233 由於4找不到比他大的,則往 1120023344 ↓╱ ├┼┼─┼┼┤ →前推移1+1位,044跟 112交換 ├───┤ └ 1120044233 1130022344 ╲ ├───┤→交換後需要rotate旋轉2次 ├─────┤ ↘1120023344 1140022334 ├┼──┼┤ →同之前的算法 1220013344 ├───┤ 1230012344 ├─────┤ 1240012334 ├┼────┼┤ →同之前的算法 1330012244 ├─────┤ 1340012234 ├┼──────┼┤→原本要交換兩個因為到底了就只換一個 1440012233 ├┼┼───┼┼┤ →同之前的算法 2230011344 ├─────┤ 2240011334 ├┼────┼┤ 2330011244 ├─────┤ 2340011234 ├┼──────┼┤→原本要交換兩個因為到底了就只換一個 2440011233 ├┼┼─────┼┼┤→原本要交換三個因為到底了就只換兩個 3340011224 ├┼──────┼┤→原本要交換兩個因為到底了就只換一個 3440011223 ├────────┤ →完全找不到比 344還大的就旋轉 3次。 並 return false 0011223344 我想問一下: 0.這是正確得演算法嗎? 1.這個演算法的時間複雜度是O(n)嗎? 2.有更有效率的做法嗎? 3.這個演算法好不好實作? -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 163.23.35.94

12/09 17:14,
我比較有問題的是 04 和 11 交換,要怎麼判斷選擇 11 ?
12/09 17:14

12/09 17:15,
又 1, 1 不一定相連呀,所以可能每次要 sort 一次
12/09 17:15

12/09 17:15,
rotate 的部分應該是 sort 吧,用 sort 才能保證找到最小字
12/09 17:15

12/09 17:15,
點序
12/09 17:15

12/09 17:17,
例如 ss("0014433221") 呢?
12/09 17:17

12/09 17:30,
next_combination跟next_permutation一樣 使用前要先排序
12/09 17:30
0041122334 └─────── →一直找不到比4大的 0041122334 └─┘ →找到比0大的 0041122334 ├─┤ →交換0跟1 0140122334 ├─┤ →交換4跟1 0110422334 ├────┤ →交換後需要rotate旋轉1次 0110223344 1340012234 └─────── →一直找不到比4大的 1340012234 └───────┘ →找到比3大的 1340012234 ├───────┤ →交換3跟4 1440012233 ├─────── →這邊因為沒東西可以換了就不用換了 1440012233 也不用旋轉了

12/09 17:36,
next_permutation() 不用吧..這是他方便之所在..
12/09 17:36
0014433221 他是某一個 next_permutation 的解 (解1可以疊代出解2) 不是我的 next_combination 的解 (我認為的) 不過可以加上 sort 來轉換 這個倒是可以加進去 說明可以這樣寫明 如果輸入不屬於解空間之一則會轉換到下一個解 0014433221 -> 0021123344 ※ 編輯: chrisdar 來自: 163.23.35.94 (12/09 17:57) -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 163.23.35.94

08/18 13:31, , 1F
推一下,感覺打的很辛苦
08/18 13:31, 1F
文章代碼(AID): #19Fa4jXh (Prob_Solve)
文章代碼(AID): #19Fa4jXh (Prob_Solve)