全排列在笔试面试中很热门,因为它难度适中,既可以考察递归实现,又能进一步考察非递归的实现,便于区分出考生的水平。所以在百度和迅雷的校园招聘以及程序员和软件设计师的考试中都考到了,因此本文对全排列作下总结帮助大家更好的学习和理解。对本文有任何补充之处,欢迎大家指出。
首先来看看题目是如何要求的(百度迅雷校招笔试题)。
用C++写一个函数, 如 Foo(const char *str), 打印出 str 的全排列,
如 abc 的全排列: abc, acb, bca, dac, cab, cba
一.全排列的递归实现
为方便起见,用123来示例下。123的全排列有123、132、213、231、312、321这六种。首先考虑213和321这二个数是如何得出的。显然这二个都是123中的1与后面两数交换得到的。然后可以将123的第二个数和每三个数交换得到132。同理可以根据213和321来得231和312。因此可以知道——全排列就是从第一个数字起每个数分别与它后面的数字交换。找到这个规律后,递归的代码就很容易写出来了:
运行结果如下:

注意这样的方法没有考虑到重复数字,如122将会输出:

这种输出绝对不符合要求,因此现在要想办法来去掉重复的数列。
二.去掉重复的全排列的递归实现
由于全排列就是从第一个数字起每个数分别与它后面的数字交换。我们先尝试加个这样的判断——如果一个数与后面的数字相同那么这二个数就不交换了。如122,第一个数与后面交换得212、221。然后122中第二数就不用与第三个数交换了,但对212,它第二个数与第三个数是不相同的,交换之后得到221。与由122中第一个数与第三个数交换所得的221重复了。所以这个方法不行。
换种思维,对122,第一个数1与第二个数2交换得到212,然后考虑第一个数1与第三个数2交换,此时由于第三个数等于第二个数,所以第一个数不再与第三个数交换。再考虑212,它的第二个数与第三个数交换可以得到解决221。此时全排列生成完毕。
这样我们也得到了在全排列中去掉重复的规则——去重的全排列就是从第一个数字起每个数分别与它后面非重复出现的数字交换。下面给出完整代码:
运行结果如下:

OK,到现在我们已经能熟练写出递归的方法了,并且考虑了字符串中的重复数据可能引发的重复数列问题。那么如何使用非递归的方法来得到全排列了?
三.全排列的非递归实现
要考虑全排列的非递归实现,先来考虑如何计算字符串的下一个排列。如"1234"的下一个排列就是"1243"。只要对字符串反复求出下一个排列,全排列的也就迎刃而解了。
如何计算字符串的下一个排列了?来考虑"926520"这个字符串,我们从后向前找第一双相邻的递增数字,"20"、"52"都是非递增的,"26 "即满足要求,称前一个数字2为替换数,替换数的下标称为替换点,再从后面找一个比替换数大的最小数(这个数必然存在),0、2都不行,5可以,将5和2交换得到"956220",然后再将替换点后的字符串"6220"颠倒即得到"950226"。
对于像"4321"这种已经是最“大”的排列,采用STL中的处理方法,将字符串整个颠倒得到最“小”的排列"1234"并返回false。
这样,只要一个循环再加上计算字符串下一个排列的函数就可以轻松的实现非递归的全排列算法。按上面思路并参考STL中的实现源码,不难写成一份质量较高的代码。值得注意的是在循环前要对字符串排序下,可以自己写快速排序的代码(请参阅《白话经典算法之六 快速排序 快速搞定》),也可以直接使用VC库中的快速排序函数(请参阅《使用VC库函数中的快速排序函数》)。下面列出完整代码:
测试一下,结果如下所示:

将字符串改成"cba"会输出:

至此我们已经运用了递归与非递归的方法解决了全排列问题,总结一下就是:
1.全排列就是从第一个数字起每个数分别与它后面的数字交换。
2.去重的全排列就是从第一个数字起每个数分别与它后面非重复出现的数字交换。
3.全排列的非递归就是由后向前找替换数和替换点,然后由后向前找第一个比替换数大的数与替换数交换,最后颠倒替换点后的所有数据。
转载请标明出处,原文地址:http://blog.csdn.net/morewindows/article/details/7370155
如果觉得本文对您有帮助,请点击‘顶’支持一下,您的支持是我写作最大的动力,谢谢。
分享到:
相关推荐
从给定的百度公司笔试题中,我们可以提炼出多个IT领域的知识点,主要集中在数据结构、算法、编程语言特性以及操作系统原理上。以下是对这些知识点的详细解析: ### 数据结构与算法 1. **排序算法的特性**:题目...
这些题目涵盖了计算机科学和软件工程中的多个核心概念,主要涉及数据结构、算法、操作系统、网络协议、编程语言特性和软件开发技术。以下是每个题目及其相关的知识点详解...准备这样的笔试题可以提高在IT行业的竞争力。
【标题】:“校招C&C++笔试题大全” 在求职过程中,尤其是对于计算机科学和技术相关专业的学生来说,参加公司的校园招聘笔试是至关重要的一步。"校招C&C++笔试题大全"是一个集各大公司历年校招笔试题目的资源库,...
《百度笔试题解析——C/C++编程篇》 在编程领域,尤其是对于互联网巨头百度这样的公司,技术面试和笔试是筛选优秀人才的重要环节。这份“baidu.rar”压缩包文件包含了百度公司过去笔试中出现的一些C、C++编程题目及...
本资料包集合了来自互联网,包括百度、腾讯等知名企业的笔试题目,旨在帮助求职者提升准备效率,了解实际面试可能遇到的问题。 **C/C++知识点** C/C++作为底层编程语言,其笔试题常常涉及以下几个核心概念: 1. *...
这是本人亲自总结的C++笔试题汇总,参考了网络很多C++笔试题(包括各大IT公司,游戏公司),挑选出了一些经典的题和难题做解析。 作用:对工作面试笔试和C++水平提高很有用处 内容:C++,STL等;
理解并熟练使用STL是C++程序员必备的技能之一,它能帮助编写出高效、可读性强的代码。在面试中,对STL的深入理解不仅可以展示你的技术实力,还能表现出你对编程最佳实践的追求。因此,熟悉STL的各个部分并能够灵活...
恒生电子2016年的校园招聘笔试题主要聚焦在技术方面,涵盖了C++和Java两种编程语言。作为一家在金融IT领域具有显著影响力的公司,恒生电子对求职者的编程能力有着较高的要求。以下是根据标题和描述提炼出的相关知识...
在IT行业中,笔试题是企业筛选优秀候选人的一个重要环节,特别是对于技术岗位,如C、C++和Java程序员。2015年诚迈科技的笔试题集为求职者提供了了解公司招聘标准和掌握相关技能的宝贵资源。诚迈科技是一家专注于移动...
百度校招笔试题汇总反映了互联网大厂对于应届毕业生在基础编程、逻辑思维和软件开发知识掌握程度的考察。以下是对汇总中知识点的详细解读。 1. **C++数据类型及其内存分配** 在C++中,数据类型主要分为基本类型、...
中国移动作为中国领先的电信运营商,其招聘过程通常会涵盖一系列技术和非技术类的笔试题目,旨在评估应聘者的专业技能和综合素质。对于C/C++这个标签,我们可以推断出中国移动可能对编程能力和计算机科学基础有较高...
在这个“stl练习题之四”中,我们将深入探讨如何使用STL中的简单容器类,并通过分析`main.cpp`文件来理解递归函数的应用。 首先,STL容器类是C++程序员最常使用的工具之一,它们包括数组(如`std::array`)、顺序...
- 百度笔试题涉及的矩阵相乘问题。 描述所指的知识点: - 百度笔试题中矩阵相乘题目设计思想,包括矩阵转置和矩阵乘法的步骤。 - 时间管理在编程笔试中的重要性。 标签所指的知识点: - 百度笔试题的常见类型和...
"迅雷和其他公司的一些笔试题"这个标题揭示了这是一份包含多个公司的笔试题目集合,其中可能包括迅雷公司以及其他未知的IT企业。这些题目主要用于考察应聘者的C/C++编程能力,可能涉及到语言基础、数据结构、算法、...
《C、C++经典问题,及面试笔试题》 C和C++是计算机科学中两种重要的编程语言,它们以其高效性、灵活性和底层控制能力深受程序员喜爱。在软件开发领域,掌握C和C++的基本概念、语法以及高级特性是成为优秀程序员的...
中兴公司的笔试题可能涉及到这两门语言的基础知识、语法特性、编程技巧以及高级概念等多个方面。 首先,Java是一种面向对象的语言,以其“一次编写,到处运行”的特性著称。在Java笔试题中,可能会考察以下知识点:...
在IT行业的招聘过程中,笔试题是企业筛选优秀人才的重要手段之一。这份名为“IT企业笔试题汇总(共52套)”的压缩包文件,包含了大量来自不同IT公司的笔试题目,旨在帮助求职者准备和提升自己的技能。这些题目涵盖了...
"2009华为-百度笔试题目.zip"标签表明这份资料是以压缩文件的形式存在,文件名为“2009华为-百度笔试题目”,很可能包含了当年的笔试题目文档或PDF文件,应聘者可以通过解压文件来获取具体题目内容。 【潜在知识点...
在各大企业的招聘过程中,C++笔试题是评估候选人编程技能和理解力的重要手段。以下是一些C++笔试题中常见的知识点,以及它们的详细解释。 1. **基础语法**:C++的基础包括变量、数据类型(如int、float、char等)、...
《Effective STL》是一本专注于C++标准模板库(STL)使用的指南书籍,由Scott Meyers撰写。书中详细讲解了如何有效地使用STL中的容器、迭代器、算法和函数对象,以及如何避免常见的陷阱和误区。本书针对的读者是已经...