字符串的全排列递归&非递归算法

本文详细介绍了如何实现字符串的全排列,包括递归和非递归两种方法。递归算法通过交换首位字符实现,非递归算法则利用字典序寻找下一个排列。对于含有重复字符的情况,可以通过标记法避免重复。文中还提供了具体的代码解析和例子。
摘要由CSDN通过智能技术生成

字符串的全排列

写在前面:本文章为根据七月算法的讲解后的学习笔记与心得。

问题描述

给定一个字符串S[0…N-1],设计算法枚举S的全排列。

1.递归算法

思路:

举个栗子:求字符串s="1234"的全排列,有以下4类情况:
1 -(234);表示以1开头,234做全排列,具体怎么做,先不管(以下皆用此表示方法)
2-(134);表示以2开头,134做全排列
3-(214);表示以3开头,214做全排列
4-(123);表示以4开头,123做全排列
这四种情况合起来,就是1234的全排列,没毛病吧。

同理:以情况一内部为例:234做全排列
又有以下三种情况:
2-(34)
3-(24)
4-(32)

依次递归,规模逐渐减小,直到只剩最后一个字符时,直接输出整个串就好了,这也就是递归的出口。

那么问题来了,
1.如何实现以2,或者3,4开头呢?
答案是,将他们所在的位置,和首位字符进行交换就可以了鸭;
即,2原来在s[1],我们只需交换s[0]与s[1]即可;同理,3开头的话,交换s[0]与s[2]。

2.如何才能保证不重复不遗漏呢?
答案是,保证递归前字符串的顺序不变,例如1 -(234)结束后,要将字符串回到1234的顺序,才开始做2-(134),同理,在2 -(234)结束后,要将字符串回到1234的顺序,才开始做3-(134);

为啥呢?
因为每次,换下一个字符开头时,我们要进行交换,如果交换了但不恢复原位的话,那么原来的位置就可能不是原来的字符了。
这样就会造成重复或者遗漏;

直接看代码:

#include <iostream>
using namespace std;
///将字符串s,从from到to,做全排列
void FullPermutation(char*s, int from, int to) {
   
	if (from == to) {
   //递归出口,只剩最后一个字符了,按当前顺序输出字符
		for (int i = 0; i <= from; i++) {
   
			cout << s[i];
		}
		cout << endl;
		return;
	}
	for (int i = from; i <= to; i++) {
   
		swap(s[i], s[from]);//交换,即更改以另一个字符开头
		FullPermutation(s, from + 1, to);//让下一位到结尾做全排列
		swap(s[i], s[from]);//复位,很重要!!
	}
}
int main() {
   
	char s[500]; int m &#
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值