1.组合
求一个字符串的所有能组合的情况,如ABC的所有的组合为A、B、C、AB、AC、BC、ABC,即,举一个例子,从ABC中选出n=2个不同的字符有哪些选法?从A遍历到C,如果选了A就从剩下的BC中再选出一个字符即可,如果没选A,则需要从BC中选出两个字符,这就符合递归的思想,递归的出口自然就是当n减至零,递归公式为:
#include<iostream>
#include<vector>
#include<string>
using namespace std;
class Combinations {
public:
Combinations(char*);
void combination(char* str, int n, vector<char>&);
public:
vector<vector<char>> result;
};
Combinations::Combinations(char* str){
//求Cnn;Cnn-1......Cn0;
for (int i = 1; i <= strlen(str); i++) {
vector<char> result_n;
combination(str, i, result_n);
}
}
void Combinations::combination(char* str, int n, vector<char>& result_n) {
//这个停止条件是判断如果字符串地址已经到最后n却不等于零
//说明这种取法不可取所以result_n不会被放入result中
if (str == NULL || (*str == '\0' && n!= 0)){
return;
}
//递归的中止条件
if (n == 0) {
result.push_back(result_n);
return;
}
result_n.push_back(*str);
combination(str + 1, n - 1, result_n);
result_n.pop_back();
combination(str + 1, n, result_n);
}
int main() {
char c[] = "abc";
Combinations cl(c);
for (int i = 0; i < cl.result.size(); i++) {
for (int j = 0; j < cl.result[i].size(); j++) {
cout << cl.result[i][j];
}
cout << endl;
}
return 0;
}
2.排列
对于排列问题,对于n个字符的排列问题,我们选出一个字符放在第一位,后面n-1位再进行排列就可以了,这也是符合递归情形的,怎么选呢?用第一位依次和后面的n-1个字符做交换不就形成了从n个字符选出一个的情况。
#include<iostream>
#include<string>
#include<vector>
using namespace std;
class Permutations {
public:
void Permutation(char* str) {
if (strlen(str)) {
permutation(str, 0, strlen(str));
}
}
void swap(char& a, char& b) {
char temp = a;
a = b;
b = temp;
}
void permutation(char* str, int begin, int end) {
if (begin == end - 1) {
result.push_back(str);
}
else {
for (int i = begin + 1; i < end; i++) {
if (i == begin) {
permutation(str, begin + 1, end);
}
if (str[i] != str[begin]) {
swap(str[i], str[begin]);
permutation(str, begin + 1, end);
swap(str[i], str[begin]);
}
}
}
public:
vector<string> result;
};
int main() {
Permutations per;
char str[] = "abcdascgf";
per.Permutation(str);
for (int i = 0; i < per.result.size(); i++) {
cout << per.result[i] << endl;
}
return 0;
}
牛客网上的一个题要求按照字典序排列,所以我给result加了一个快排。
int Partition(vector<string>& A, int high, int low) {
string x = A[high];
int i = low - 1;
for (int j = low; j < high; j++) {
if (A[j] < x) {
i++;
string temp;
temp = A[i];
A[i] = A[j];
A[j] = temp;
}
}
A[high] = A[i + 1];
A[i + 1] = x;
return i + 1;
}
void quicksort(vector<string> &A, int high, int low) {
if (high > low) {
int k = Partition(A, high, low);
quicksort(A, high, k + 1);
quicksort(A, k - 1, low);
}
}