题目概述
昨天做了一套CVTE的面试题,最后一个题目就是字符串的全排列。做过剑指Offer的童鞋一眼就可以看出这是剑指Offer-28题
原题目,一点都没变
题目解法
把字符串看成两个部分,第一个部分为第一个字符,剩下的是后面的字符
首先将所有可能出现在第一个位置的字符,将这些字符在每次循环的时候和第一个字符交换、
先固定一个字符,求后面字符的排列
然后将后面的字符按照前面的方法分成两部分,递归
代码实现
//面试题28:字符串的全排列
//pstr表示要打印的字符串,pbegin表示从该位置开始交换字符
void _Per(char* pstr, size_t start, size_t end)
{
//要交换的字符指针已经到末尾,此时可以打印pstr字符串了
if (start == end - 1)
{
printf("%s\n", pstr);
return;
}
//注意,这里pCh不能初始为pbegin+1
for (size_t index = start; index != end; ++index)
{
//依次交换后面的一个字符
std::swap(pstr[start], pstr[index]);
//进行递归
_Per(pstr, start + 1, end);
//将该字符还原
std::swap(pstr[start], pstr[index]);
}
}
void Per(char* pstr)
{
if (pstr == NULL)
return;
_Per(pstr, 0, strlen(pstr));
}
void TestPer()
{
char str[] = "abcd";
Per(str);
cout << endl;
}
几个注意的地方
1、cout<<*pstr; 只能打印当前的一个字符,并不能打印字符串;还是用printf("%s",pstr);
2、原书中用的都是指针,原书中交换是手动交换的,而我这里用下标来表示,用偏移加解引用比较方便点,不易出错
3、std::swap交换要注意,不能写成交换两个指针了
网上的另一种解法
用STL提供的算法
sort和next_permutation可以快速的求出全排列
代码实现
#include<algorithm>
void Per(char *str)
{
int len = strlen(str);
sort(str, str + len);
//传入迭代器区间
while (next_permutation(str, str + len))
{
printf("%s ,", str);
}
}
void TestPer()
{
char str[] = "abcd";
Per(str);
cout << endl;
}