全排列问题的递归、STL实现

原文代码地址:

http://blog.csdn.net/morewindows/article/details/7370155(原文很详细,博主很强大!)

 

//全排列的递归实现
#include <stdio.h>
#include <string.h>
#include<iostream>
using namespace std;
void Swap(char *a, char *b)
{
	char t = *a;
	*a = *b;
	*b = t;
}
//k表示当前选取到第几个数,m表示共有多少数.
void AllRange(char *pszStr, int k, int m)
{  
	static int count=0; 
	count++;
	if (k == m)
	{
		cout<<"#"<<count<<" "<<k<<endl;
		static int s_i = 1;
		printf("  第%3d个排列\t%s\n", s_i++, pszStr);
	}
	else
	{
		cout<<"*"<<count<<" "<<k<<endl;
		for (int i = k; i <= m; i++) //第i个数分别与它后面的数字交换就能得到新的排列
		{
			cout<<"$"<<count<<" "<<k<<"  "<<i<<endl;
			Swap(pszStr + k, pszStr + i);
			AllRange(pszStr, k + 1, m);
			Swap(pszStr + k, pszStr + i);
			cout<<"@"<<count<<" "<<k<<" "<<i<<endl;
		}
	}
}
void Foo(char *pszStr)
{
	AllRange(pszStr, 0, strlen(pszStr) - 1);
}
int main()
{
	printf("         全排列的递归实现\n");
	printf("  --by MoreWindows( http://blog.csdn.net/MoreWindows )--\n\n");
	char szTextStr[] = "123";
	printf("%s的全排列如下:\n", szTextStr);
	Foo(szTextStr);
	getchar();
	return 0;
}


 

由于源代码递归,初学者很难看懂到底递归到那里去了,怎么递归的,又是怎么实现全排列的等等一系列问题,通过看上图,再加上在纸上画一画,估计会好理解很多的。

由上图可见,1,2,3.....10为调用AllRange函数的次数,对应不同位置,我用了不同的符号标注,并输出了 i  k 的值,发现了如下规律:

先输出了  123 ,132 后,通过swap又将 132 转为了 123,

接着是输出了 213,231(即对123进行了第一位与第二位交换,再进行了第二位与第三位交换),然后又把 231 转为了123,

接着输出321 ,312。

 

这种递归的算法,我感觉我作为初学者,一次肯定理解不到位,多学才行啊。

 

还有一种神奇的方法,C++强大的STL,可以通过调用next_permutation函数完美解决。

贴上代码,大家欣赏:

#include <iostream>
#include <algorithm>
#include <string>
 
using namespace std;
 
int main()
{
    string str;
	cout<<"请输入:";
    cin >> str;
    sort(str.begin(), str.end());
	cout<<"全排列结果:"<<endl;
    cout << str << endl;
    while (next_permutation(str.begin(), str.end()))
    {
        cout << str << endl;
    }
	system("pause");
    return 0;
}


 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值