字典序算法
1、字典序的概念
据说字典序是个比较经典的算法,也不知道出自哪里。。。用一个例子说明什么是字典序,对于1、2、3,按照如下排序:
123 132 213 231 312 321
这些排序从左到右依次增大,就是所谓的字典序。
2、查找字典序的下一个数对于已有的排序的一个排序,怎么得到其字典序的下一个排列呢?
①从右到左找到第一个左边小于右边的数字; (这一步是确定一个增加的位置,该位置需要保证增加之后对整体的增加较小)
②如果没有找到①中de数字,说明已经是最后一个排列,比如321;
如果找到第i个元素,说明可以得到下一个排列,入132,找到了1。
③从右到左找到第一个大于i元素的j元素,如132中找到了2;(这一步找到一个用户交换的数字,因此从大于该位置的数中找到一个最小的)
④交换i、j元素的位置,如132,交换完成为231;
⑤对i之后的元素进行排序,排序完成为213;
3、字典序生成全排列
方法1:
①对所有元素进行升序排序,得到最小的排列;
②按照2中的方法循环得到下一个排列,直至最大
方法2:
方法1中需要提前对元素进行一次排序,如果从当前排列开始,同上向前找到排列和向后找到排列,就不需要提前进行排序了
//找到下一个遵循字典序的排列
bool findNext(string &str)
{
int num = str.size();
int i, j;
//从右向左,找到第一个左边小于右边的数,如54231,则找到2
for(i=num-2; i>=0; i--)
{
if(str[i] < str[i+1])
{
break;
}
}
//如果没有找到,说明已经最大
if(i<0)
{
return false;
}
//从右向左,找到第一个大于str[i]的元素,如54231,则找到3
for(j=num-1; j>i; j--)
{
if(str[j] > str[i])
{
break;
}
}
//交换i、j位置字符,如54321,交换完成后是54312
int temp = str[i];
str[i] = str[j];
str[j] = temp;
//对i之后的元素进行排序,排序完成后为54123
sort(str.begin()+i+1, str.end());
return true;
}
vector<string> Permutation(string &str) {
vector<string> v;
int len = str.size();
if(len <= 0)
{
return v;
}
sort(str.begin(), str.end());
v.push_back(str);
while(findNext(str) == true)
{
v.push_back(str);
}
return v;
}