------------只要够努力,人生最坏的结局不过是大器晚成!!!

https://www.nowcoder.com/acm/contest/76/H

给一道题,可以去测试代码。

这里总结一下全排列的几种方法:

方法一:利用交换排列:缺点:不能按字典序排列,但可以借助set处理。

#include <bits/stdc++.h>  //不会按字典序排列 
using namespace std;

void pre(string str, int s, int e){
	if(s == e){
		cout << str << endl;
	}
	else{
		for(int i = s; i <= e; i++){
			if(i != s && str[i] == str[s]) //去重,除了第一位,其余的相同时无须交换 
				continue;
			swap(str[i], str[s]);
			pre(str, s + 1, e);
			swap(str[i], str[s]);
		}
	}
}

int main(){
	string str;
	cin >> str;
	pre(str, 0, str.length() - 1);
	return 0;
}

  方法二:利用dfs,只能处理没有重复元素的字符串

#include <bits/stdc++.h>
using namespace std;
char str[100];
char mu[100];

void dfs(int len, int n){
	if(len == n){
		cout << mu << endl;
		return ;
	}
	for(int i = 0; i < n; i++){ //尝试放入每个字符 
		int flag = 1;
		for(int j = 0; j < len; j++){ //检测这个字符是否已经放入过 
			if(mu[j] == str[i]){
				flag = 0;
				break;
			}
		}
		if(flag){
			mu[len] = str[i];
			dfs(len + 1, n); 
		}
	}
}

int main(){
	cin >> str;
	
	sort(str, str + strlen(str)); 
	dfs(0, strlen(str));
	
	return 0;
}

  方法三:dfs: 感觉这个是比较理想的,可以按字典序排好输出,并能去重,一定要掌握!!!

对于A1,B,A2进行排序,(这里的A1, A2代表相同元素,下标是为了区分)
首先sort一下变成:A1,A2,B
然后第一趟:
A1,A2,B
A1, B, A2
然后遍历到A2开头了,好,后面查找下一个时,从i=0开始,
于是判断A1是否访问过,未访问则进行最关键的步骤了:
检测A1之后是否有已访问的且和A1相等,如若是则放弃A1继续遍历。
这里有点不好理解,对于A1A2B的序列,可知A1再前所以以A开头的
必定是以A1开头,所以在尝试A2开始头时,遍历尝试放入第二个元
素时判断A1虽然当前未访问过,但他是在A2之前,一定在之前的全
排列之中了,故放弃。
感觉还是不太好理解;还是自己在纸上画画,模拟一下,多体会体会。

 

#include <bits/stdc++.h>
using namespace std;
const int N = 1e3;
char str[N];
char buf[N]; 
int toal, len;
bool visit[N];

void pre(int num){
	if(num == len){
		cout << buf << endl;
		toal++;
		return ;
	}
	for(int i = 0; i < len; i++){
		if(!visit[i]){
			bool flag = 1;
			for(int j = i + 1; j < len; j++){
				if(visit[j] && str[j] == str[i]){ //检测重复 
					flag = 0;
					break;
				}
			}
			if(flag){
				buf[num] = str[i]; //这里不能写成:buf[num++] = str[i];因为for循环没有结束还要用num,不能改变num的值 
				visit[i] = 1;
				pre(num + 1); 
				visit[i] = 0;
			}
		}
	}
}

int main(){
	cin >> str;
	len = strlen(str);
	sort(str, str + len);
	pre(0);
	cout << "toal: " << toal << endl;
	return 0;
}

 

  

 

posted on 2018-03-08 20:20  ystraw  阅读(225)  评论(0编辑  收藏  举报

不经一番切孤寒,怎得梅花扑鼻香