我想通过递归获取列表元素的所有置换

I want to get every permutation of list elements via recursion

本文关键字:列表元素 获取 递归      更新时间:2023-10-16

我想获得清单元素的所有置换。我正在尝试通过在两个列表之间调整这些元素并检查list2的迭代来做到这一点。

虽然有问题。您能帮我解决我的问题吗?

void iterlist(list<int>& Lit)
{
    list<int>::iterator it;
    for (it=Lit.begin(); it!=Lit.end(); it++)
        cout << " " << *it;
    cout << endl;
}
void permutations(list<int>& L1, list<int>& L2)
{
    L2.push_back(L1.front());
    L1.pop_front();
    if(!L1.empty())
    {
        permutations(L1, L2);
    }
    L1.push_back(L2.back());
    L2.pop_back();
    iterlist(L2);
}

我正在为L1 = 1,2,3,4,5的元素进行测试,而我获得的唯一排列是:1 2 3 4 55 4 3 2 1

递归从n项列表中递归生成n长度的置换的一般算法是:

对于列表中的每个元素

中的每个元素
  • 在没有元素x的情况下制作列表的副本;称其为newlist
  • 找到新清单的所有排列(就是递归,顺便说一句)
  • 将元素添加到新列表的每个置换的开头

还有其他方法可以做到这一点,但是我一直发现这是最容易学习递归来缠绕头的人。您似乎正在使用的方法涉及将算法的迭代循环部分存储在第二个列表中,这完全很好,但是我警告您在这样做时要管理订单交换的算法并不是立即直观 - 在适当的时候发现发现)。

以下是一般算法(并非特别有效,但您可以从中获得一般想法)。

#include <iostream>
#include <list>
typedef std::list<int> IntList;
void iterlist(IntList& lst)
{
    for (IntList::iterator it=lst.begin(); it!=lst.end(); it++)
        cout << " " << *it;
    cout << endl;
}
std::list<IntList> permute(IntList& L1)
{
    if (L1.size() == 1)
        return std::list<IntList>(1,L1);
    std::list<IntList> res;
    for (IntList::iterator i = L1.begin(); i != L1.end();)
    {
        // remember this
        int x = (*i);
        // make a list without the current element
        IntList tmp(L1.begin(), i++);
        tmp.insert(tmp.end(), i, L1.end());
        // recurse to get all sub-permutations
        std::list<IntList> sub = permute(tmp);
        // amend sub-permutations by adding the element
        for (std::list<IntList>::iterator j=sub.begin(); j!=sub.end();j++)
            (*j).push_front(x);
        // finally append modified results to our running collection.
        res.insert(res.begin(), sub.begin(), sub.end());
    }
    return res;
}
int main()
{
    IntList lst;
    for (int i=0;i<4;i++)
        lst.push_back(i);
    std::list<IntList> res = permute(lst);
    for (std::list<IntList>::iterator i=res.begin(); i!=res.end(); i++)
        iterlist(*i);
    return 0;
}

产生以下输出,所有排列为0..3:

 3 2 1 0
 3 2 0 1
 3 1 2 0
 3 1 0 2
 3 0 2 1
 3 0 1 2
 2 3 1 0
 2 3 0 1
 2 1 3 0
 2 1 0 3
 2 0 3 1
 2 0 1 3
 1 3 2 0
 1 3 0 2
 1 2 3 0
 1 2 0 3
 1 0 3 2
 1 0 2 3
 0 3 2 1
 0 3 1 2
 0 2 3 1
 0 2 1 3
 0 1 3 2
 0 1 2 3