全排列问题

中午看到的一个题目。
求一个不重复字符串的全排列。

主要有递归,字典序等解决方案。然后想到stl里的next_permutation()函数,利用的便是字典序的方式。主要原理如下:

在当前序列中,从尾端往前寻找两个相邻元素,前一个记为i,后一个记为ii,并且满足i < ii。然后再从尾端寻找另一个元素j,如果满足i < *j,即将第i个元素与第j个元素对调,并将第ii个元素之后(包括ii)的所有元素颠倒排序,即求出下一个序列了。
在纸上画了半天,才把细节搞清楚了,确实很优雅的实现方式,很有启发性。

至于递归的方式,基于交换的思路,代码大体如下:

std::swap(val[i-1],val[k]);        
full_permutation(val,n,i+1);       
std::swap(val[i-1],val[k])  

看似很简单的三行,却很难模拟。
脑袋里想了半天,还是觉得很抽象。
不过这个算法最巧妙的地方还是利用字符串本身作为操作原型,没有引入其他结构存储字符串。

想来想去,觉得还是蛮复杂,遂自己写了一个python的版本,利用了yield特性,感觉好理解的多,如下:

def full_permutation(str):
    if (1 >= len(str)):
        yield str
    else:
        for i in full_permutation(str[1:]):
            for j in range(len(i) + 1):
                yield i[0:j] + str[0] + i[j:]   

只有7行。
思路也很简单,同样是利用递归的原理。
假如初始的字符串是a,字符串集合为{[a]}, 当加入b时,b的插入位置有a前和a后两个位置,插入后,新的字符串集合变为:
{[b, a], [a, b]}。当加入c时,对于[b, a],c的插入位置有3个,b前,a前,a后,也就是说:
[b, a] + c => [c, b, a], [b, c, a], [b, a, c],对于[a, b]也是同理。
概括来说,就是将每一个字符,插入每一个可能的位置。
(原文时间2013-9-16)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 在C语言中,五种基本数据类型存储空间长度的排列顺序是: A)char B)char=int<=float C)ch...
    夏天再来阅读 3,438评论 0 2
  • 专业考题类型管理运行工作负责人一般作业考题内容选项A选项B选项C选项D选项E选项F正确答案 变电单选GYSZ本规程...
    小白兔去钓鱼阅读 9,090评论 0 13
  • 首先考虑一道奥数题目: □□□ + □□□ = □□□,要将数字1~9分别填入9个□中,使得等式成立。例如173+...
    SHY圆圆圈圈圆圆阅读 3,487评论 4 7
  • 描述 给定一个由不同的小写字母组成的字符串,输出这个字符串的所有全排列。 我们假设对于小写字母有'a' < 'b'...
    includes阅读 1,131评论 0 1
  • 今天学习了字符串全排列问题的递归与非递归实现,其中,递归实现是把递归放在循环中,到现在我也没看懂到底是个什么样的过...
    pw007992阅读 769评论 0 1