递归之全排列问题

一、问题

设计一个递归算法生成n个元素{r1,r2,…,rn}的全排列。

二、思路

其实就是将整个序列A={ri,ri+1,ri+2......rj}的每个元素一一提到序列A首个位置即A[i] (ri)处,然后对A[i+1]......A[j]这些元素组成的序列全排列,也就是对除了首元素的剩余序列递归进行全排列,直到剩余序列只剩一个元素,打印当前序列。注意每次将元素调到当前序列首个位置、然后对剩余序列全排列之后,要将元素换回原来的位置。全排列的结果总共有n!种,比如当对于序列{1,2,3},n=3,那么结果就有3!=6种。

三、代码

#include <iostream>
using namespace std;

void swap (int &a, int &b)
{
	int temp=a;
	a=b;
	b=temp;
}

// list[k:m]的所有排列,k是序列首下标,m是序列最后一个下标
void perm (int list[], int k, int m)
{
	if (k==m)
	{
		for (int i=0; i<=m; i++)
            cout<<list[i]<<" ";
		cout<<endl;
	}
	else
		for (int i=k; i<=m; i++)
		{
			swap(list[k], list[i]);
			perm(list, k+1, m);
			swap(list[k], list[i]);
		}
}
int main()
{
	int A[]= {1,2,3};
	perm(A,0,2);
	system("pause");
	return 0;
}

运行结果:

。。但是上面的算法只能找出元素都不相同的序列的全排列,像我们遇到{"1","2","2","3"}这样有重复元素的序列就尴尬了,所以改进下,同时我还把数据类型改了,反正都一样的:

#include <iostream>
#include <string>
#include <vector>
using namespace std;

void swap (string &a, string &b)
{
	string temp=a;
	a=b;
	b=temp;
}

// list[k:m]的所有排列,k是序列首下标,m是序列最后一个下标
void perm (vector<string> list, int k, int m)
{
	if (k==m)
	{
		string s="";
		for (int i=0; i<=m; i++)
		{
			s.append(list[i]);
		}

		cout<<s<<endl;
	}
	else
		for (int i=k; i<=m; i++)
		{
			bool flag=false;
			//检查重复元素
			for(int p=k; !flag && p<i; p++)
			{
				if(list[p]==list[i])
				{
					flag=true;
				}
			}
			if(flag)continue;
			swap(list[k], list[i]);
			perm(list, k+1, m);
			swap(list[k], list[i]);
		}
}
int main()
{
	string A0[]= {"1","2","2","3"};
	vector<string> A(A0,A0+4);
	perm(A,0,3);
	system("pause");
	return 0;
}

运行结果:

可以看到结果没有重复的、啦!

猜你喜欢

转载自blog.csdn.net/qq_32919451/article/details/81610864
今日推荐