最近想要好好學一下算法,但是老覺得無從下手,論壇上有童鞋推薦一個臺灣的網站http://www.csie.ntnu.edu.tw 覺得很不錯,這裏就當是個學習日誌吧。。就是代碼有的地方有些小問題
1. 最常見的問題:有一個集合,1-N共N個元素,輸出可能的全排列。
- #include<iostream>
- using namespace std;
- int solution[5];
- bool used[6];
- void backtracking(int n) {
- if(n == 5) {
- for(int i = 0; i < 5; i++)
- cout << solution[i] << " ";
- cout << endl;
- return;
- }
- for(int i = 1; i <= 5; i++) {
- if(!used[i]) {
- used[i] = true;
- solution[n] = i;
- backtracking(n + 1);
- used[i] = false;
- }
- }
- }
- int main() {
- for(int i = 1; i <= 5; i++)
- used[i] = false;
- backtracking(0);
- return 0;
- }
2. 如果是換成字符串,也是一樣的,但是要考慮如果有相同的字符,例如abbcc這種,需要在回溯的時候注意區分,如果之前已經在相應的位置用過就跳過本次操作
- #include<iostream>
- using namespace std;
- //int solution[5];
- bool used[6];
- char s[5] = {'a', 'b', 'b', 'c', 'c'};
- char solution[5];
- void backtracking(int n) {
- if(n == 5) {
- for(int i = 0; i < 5; i++)
- cout << solution[i];
- cout<<endl;
- return;
- }
- char last_letter = '\0';
- for(int i = 0; i < 5; i++) {
- if(used[i]) continue;
- if(s[i] == last_letter) continue;
- last_letter = s[i];
- used[i] = true;
- solution[n] = s[i];
- backtracking(n+1);
- used[i] = false;
- }
- }
- int main() {
- for(int i = 0; i < 5; i++)
- used[i] = false;
- backtracking(0);
- return 0;
- }
3.給定一個集合類似{0,1,2,3,4},求出所有的子集合
- #include<iostream>
- using namespace std;
- int array[5] = {0, 1, 2, 3, 4};
- int subset[5];
- void backtracking(int i, int n) {
- if(i == 5) {
- for(int i = 0; i < n; i++)
- cout << subset[i] << " ";
- cout << endl;
- return;
- }
- subset[n] = array[i];// choose this value into the subset
- backtracking(i + 1, n + 1);
- backtracking(i + 1, n);//don't choose the value and continue to backtrack
- }
- int main() {
- backtracking(0, 0);
- return 0;
- }