时间:2021-05-22
题目描述:
设计一个程序,当输入一个字符串时,要求输出这个字符串的所有排列。
例如输入字符串 abc,要求输出由字母 a、b、c 所能排列出来的所有字符串 abc,acb,bac,bca,cab,cba。
方法:递归法
以字符串 abc 为例介绍对字符串进行全排列的方法。
(1) 首先固定第一个字符 a,然后对后面的两个字符 b、c 进行全排列;
(2) 交换第一个字符与其后面的字符,即交换 a 与 b,然后对后面的两个字符 a与c 进行全排列;
(3) 由于第二步交换了 a与b 破坏了字符串原来的顺序,所以需要再次交换 a与b 使其恢复到原来的顺序,然后交换第一个字符与第三个字符(交换a和c),接着固定第一个字符c,对后面的两个字符 a与b 求全排列。
在对字符串求全排列的时候就可以采用递归的方式求解。
在使用递归求解的时候,要注意:
(1) 逐渐缩小问题的规模,并且可以用同样的方法来求解子问题;
(2) 递归一定要有结束条件,否则会导致程序陷入死循环;
代码实现:
#!/usr/bin/env python3# -*- coding: utf-8 -*-# @Time : 2020/2/3 9:49# @Author : buu# @Software: PyCharm# @Blog :https://blog.csdn.net/weixin_44321080def swap(str, i, j): # 交换字符数组下标为i和j对应的字符 tmp = str[i] str[i] = str[j] str[j] = tmpdef permutation(str, start): """ 对字符串中的字符进行全排列 :param str: 待排序的字符串,list :param start: 待排序的子字符串的首字符下标 :return: """ if str == None or start < 0: return if start == len(str) - 1: # 完成全排列后输出当前排列的字符串 print(''.join(str),end=' ') else: i = start while i < len(str): # 交换start与i所在位置的字符 swap(str, start, i) # 固定第一个字符,对剩余的字符进行全排列 permutation(str, start + 1) # 还原start与i所在位置的字符 swap(str, start, i) i += 1def permutation_transe(s): str = list(s) permutation(str, 0)if __name__ == '__main__': s = 'abc' permutation_transe(s)结果:
算法性能分析:
假设这种方法所需的基本操作数为 f(n),f(n) = n×f(n-1) = …= n!
所以时间复杂度为O(n!);
空间复杂度为O(1);
引申:
如何去掉重复的排列?
当字符串中没有重复的字符的时候,它的所有组合对应的字符串就没有重复的情况;当时当字符串中有重复的字符的时候,例如 ‘baa',此时如果按照上面介绍的算法求全排列会有重复的字符串。
思路:
全排列的主要思路为:从第一个字符起每个字符分别与它们后面的字符进行交换:例如对于“baa”,交换 baa 第一个与第二个字符后得到“aba”,再考虑交换 baa 第一个与第三个字符后得到“aab”,由于 baa 的第二个字符与第三个字符相等,所以会导致两种交换方式得到的 aba 与 aab 对应的全排列是重复的(在固定aba与aab的第一个字符的情况下,它们对应的全排列都为 aba,aab)。
所以可以知道,去掉重复排列的主要思路为:
从第一个字符起,每个字符分别与它后面的非重复出现的字符进行交换。在递归的基础上只需要增加一个判断字符是否重复出现的函数即可。
代码实现:
#!/usr/bin/env python3# -*- coding: utf-8 -*-# @Time : 2020/2/3 10:37# @Author : buu# @Software: PyCharm# @Blog :https://blog.csdn.net/weixin_44321080#!/usr/bin/env python3# -*- coding: utf-8 -*-# @Time : 2020/2/3 9:49# @Author : buu# @Software: PyCharm# @Blog :https://blog.csdn.net/weixin_44321080def swap(str, i, j): # 交换字符数组下标为i和j对应的字符 tmp = str[i] str[i] = str[j] str[j] = tmpdef isDuplicate(str,begin,end): """ 判断 [begin,end)区间中是否有字符与 *end相等 :param begin: 指向字符的指针 :param end: 指向字符的指针 :return: 如果有相等的字符True,else False """ i=begin while i<end: if str[i]==str[end]: return True else: i+=1 return Falsedef permutation(str, start): """ 对字符串中的字符进行全排列 :param str: 待排序的字符串,list :param start: 待排序的子字符串的首字符下标 :return: """ if str == None or start < 0: return if start == len(str) - 1: # 完成全排列后输出当前排列的字符串 print(''.join(str),end=' ') else: i = start while i < len(str): # 若有重复字符,则终止当前循环,开始下一次循环 if isDuplicate(str,start,i): i+=1 continue # 交换start与i所在位置的字符 swap(str, start, i) # 固定第一个字符,对剩余的字符进行全排列 permutation(str, start + 1) # 还原start与i所在位置的字符 swap(str, start, i) i += 1def permutation_transe(s): str = list(s) permutation(str, 0)if __name__ == '__main__': s = 'baa' permutation_transe(s)结果:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
本文实例讲述了Python字符串的全排列算法。分享给大家供大家参考,具体如下:题目描述输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串ab
字符串的全排列,具体内容如下输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc
输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如,输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,
本文实例讲述了C语言实现输入一个字符串后打印出该字符串中字符的所有排列的方法,属于数学里的排列问题。是一个很实用的算法技巧。分享给大家供大家参考。具体实现方法如
本文实例讲述了Java统计一个字符串在另外一个字符串出现次数的方法。分享给大家供大家参考,具体如下:Java统计一个字符串在另外一个字符串出现次数代码如下:?1