更多C++知识:C++目录索引
全排列:
输入一个字符串,打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a、b、c所能排列出来的所有字符串abc、acb、bac、bca、cab和cba。
思路:
全排列思想主要分为三部分:
- 从右向左找出
第一对右大于左
的字符对- 从右向左找
第一个大于左边字符大
的字符,进行交换- 找出需要逆置的区间
下面看一个例子:字符串为1 2 3
至此,1作为第一个元素的情况已经排列完毕,接下来排列2作为首元素的情况
剩下的情况重复上面的步骤,不在画图,下面看代码
bool perm(vector<int>& v)
{
int length = v.size();//数组长度
vector<int>::iterator left = v.end();
--left;//指向倒数第二个
vector<int>::iterator right = left;
--left;//指向倒数第一个数字
//找出第一对左小右大的数
while (right != v.begin() && *left >= *right)
{
if (--right != v.begin())
{
--left;
}
}
if (right == v.begin())//当right走到最开始的位置,表示全部已经排完,不需要在进行排列
{
reverse(right, v.end());
return false;
}
vector<int>::iterator last = v.end() - 1;//指向最后一个数
while (*last <= *left)//找出从右往左第一个比left大的数字
{
--last;
}
swap(*left, *last);//将last和left进行交换
reverse(right, v.end());//在将right往后的数据进行逆置
return true;
}
void Print(vector<int>& v)
{
vector<int>::iterator it1 = v.begin();
while (it1 != v.end())
{
cout << *it1 << " ";
++it1;
}
cout << endl;
}
void test()
{
vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);
BDIterator first = v.begin();
BDIterator last = v.end();
do
{
Print(v);
} while (perm(v));
}
结果: