字符全排列+递归

字符串全排列

给定一组互不相同的字符,求这组字符的全排列。

输入:

输入一个字符串
ABC

输出:

输出该字符的全排列,排列的先后顺序不影响结果。
ABC ACB BAC BCA CAB CBA

思路:

只需考虑让每一个字符都做首字符的可能,然后其子串也是如此。

代码

#include<stdio.h>
#include<string.h>
char str[1000];
void Swap(char *a,char *b)
{
	char temp=*a;
	*a=*b;
	*b=temp;
}
void solve(int from,int to)
{
	if(from==to)//递归边界;
	{
		printf("%s ",str);
		return;
	} 
	for(int i=from;i<=to;i++)
	{
		Swap(&str[from],&str[i]);//首字符的排列排完后,换下一个字符做首字符 
		solve(from+1,to);//递归处理子串的全排列 
		Swap(&str[from],&str[i]);//每一个首字符排列完后,交换回来。 
	}
}
int main()
{
	scanf("%s",&str);
	int len=strlen(str);
	solve(0,len-1);
	return 0;
}

如果改变一下题目,输入一个可重复的字符串。
我们只需考虑,首字符下一次不能重复。加一个判断条件即可。

代码

#include<stdio.h>
#include<string.h>
char str[1000];
void Swap(char *a,char *b)
{
	char temp=*a;
	*a=*b;
	*b=temp;
}
bool judge(int from,int to)//判断有没有重复数字打头 
{
	for(int i=from;i<to;i++)
	{
		if(str[i]==str[to])
		{
			return false;
		}
	}
	return true;
}
void solve(int from,int to)
{
	if(from==to)//递归边界;
	{
		printf("%s\n",str);
		return;
	} 
	for(int i=from;i<=to;i++)
	{
		if(judge(from,i))
		{
			Swap(&str[from],&str[i]);//首字符的排列排完后,换下一个字符做首字符 
			solve(from+1,to);//递归处理子串的全排列 
			Swap(&str[from],&str[i]);//每一个首字符排列完后,交换回来。 
		}
	}
}
int main()
{
	scanf("%s",&str);
	int len=strlen(str);
	solve(0,len-1);
	return 0;
}

这个算法的复杂度为(n+1)!的,本题可以用空间换时间,转化为n!。

#include<cstdio>
#include<cstring>
#include<algorithm> 
using namespace std;
const int MAXN=1e5;
char str[MAXN];
void solve(int from,int to)//解决重复数字问题。用空间换时间 
{
	if(from==to)//递归边界
	{
		printf("%s\n",str);
		return;
	} 
	int mask[256]={};
	for(int i=from;i<=to;i++)	mask[str[i]]=0;
	for(int i=from;i<=to;i++)
	{
		if(mask[str[i]]==1)	continue;
		mask[str[i]]=1;
		swap(str[from],str[i]);
		solve(from+1,to);
		swap(str[from],str[i]);
	}
} 
int main()
{
	scanf("%s",&str);
	int len=strlen(str);
	solve(0,len-1);
	return 0;
} 
发布了39 篇原创文章 · 获赞 1 · 访问量 566

猜你喜欢

转载自blog.csdn.net/qq_45249273/article/details/104427848
今日推荐