作者chrisdar (克里斯)
看板Prob_Solve
標題[問題] 關於重複組合的演算法問題
時間Tue Dec 9 17:58:04 2008
※ [本文轉錄自 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
推 gba356:我比較有問題的是 04 和 11 交換,要怎麼判斷選擇 11 ? 12/09 17:14
→ gba356:又 1, 1 不一定相連呀,所以可能每次要 sort 一次 12/09 17:15
→ gba356:rotate 的部分應該是 sort 吧,用 sort 才能保證找到最小字 12/09 17:15
→ gba356:點序 12/09 17:15
→ gba356:例如 ss("0014433221") 呢? 12/09 17:17
→ chrisdar: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 也不用旋轉了
推 gba356: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
推 hannibal0416:推一下,感覺打的很辛苦 08/18 13:31