STL -------- 全排列算法非递归

更多C++知识:C++目录索引


全排列:

  输入一个字符串,打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a、b、c所能排列出来的所有字符串abc、acb、bac、bca、cab和cba。

思路:

全排列思想主要分为三部分:
1. 从右向左找出第一对右大于左的字符对
2. 从右向左找第一个大于左边字符大的字符,进行交换
3. 找出需要逆置的区间

下面看一个例子:字符串为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));
}

结果:

这里写图片描述

猜你喜欢

转载自blog.csdn.net/zhangye3017/article/details/80857979