字符串排列组合问题

1.组合

   求一个字符串的所有能组合的情况,如ABC的所有的组合为A、B、C、AB、AC、BC、ABC,即C^{m}_{m}+C^{m-1}_{m}......+C^{0}_{m},举一个例子,从ABC中选出n=2个不同的字符有哪些选法?从A遍历到C,如果选了A就从剩下的BC中再选出一个字符即可,如果没选A,则需要从BC中选出两个字符,这就符合递归的思想,递归的出口自然就是当n减至零,递归公式为:

                          C\in Str:

                                              if(C):combination(str + 1, n - 1);

                                              if(!C):combination(str + 1, 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);
	}
}

猜你喜欢

转载自blog.csdn.net/qq_38593211/article/details/82347556