全排列:
主要思想:将字符串第一个字符依次与后面字符交换,然后进行递归交换 在存在重复字符时需要加一个判断,判断之前是否交换过此字符。
bool isSwap(string str , int begin, int end) {
for (int i = begin; i < end; i++) {
if (str [i] == str [end])
return false ;
}
return true ;
}
void fullArrangement(string str , int l, int r) {
if (l == r) {
cout << str << endl;
}
else {
for (int i = l; i <= r; i++) {
if (isSwap(str , l, i)) {
swap(str [l], str [i]);
fullArrangement(str , l + 1 , r);
swap(str [l], str [i]);
}
}
}
}
全组合:
主要思想:同样可以利用全排列的思想,但是更简单的方法是位操作。在存在重复字符时需要有一个去重的操作。
string dropDuplicates(string str) {
string res;
int len = str.size();
int hash[256 ] = { 0 };
for (int i = 0 ; i < len ; i++) {
hash[str[i]] |= 1 ;
}
for (int i = 0 ; i < 256 ; i++) {
if (hash[i] == 1 ) {
res += char(i);
}
}
return res;
}
void fullCombination(string str, int l, int r) {
int len = str.size();
int n = 1 << len ;
for (int i = 1 ; i <= n; i++) {
for (int j = 0 ; j < len ; j++) {
if (i & (1 << j))
cout << str[j];
}
cout << endl;
}
}