(任何语言)查找元素的所有排列在使用交换载体载体、排列、元素、语言

2023-09-11 07:02:06 作者:记忆里、他很闪耀

今天我被要求在实验室会议上这个问题。

I was asked this question in a Lab session today.

我们可以想象含有的元素1,...,N的矢量 - 1,用一个长度为N是否有生成的所有排列的向量中的元素,或订单的算法(系统)方法。一个建议的方法是交换随机元素。显然,这将工作提供了所有的previously产生的排列分别保存备查,然而,这显然是一个非常低效的方法,无论是空间智慧和时间明智的。

We can imagine a vector containing the elements 1 ... N - 1, with a length N. Is there an algorithmic (systematic) method of generating all permutations, or orders of the elements in the vector. One proposed method was to swap random elements. Obviously this would work provided all previously generated permutations were stored for future reference, however this is obviously a very inefficient method, both space wise and time wise.

的原因的方式这样做是去除从在载体中,在那里不允许这样的元件的特殊位置特殊元素(例如,元件,其是零)。因此随机方法并非如此可笑,但可以想象,其中元件的数量很大的情况下的和可能的排列(这是使得存在在任何特殊位置的没有特殊元素)的数目低。

The reason for doing this by the way is to remove special elements (eg elements which are zero) from special positions in the vector, where such an element is not allowed. Therefore the random method isn't quite so ridiculous, but imagine the case where the number of elements is large and the number of possible permutations (which are such that there are no "special elements" in any of the "special positions") is low.

我们努力工作,通过这个问题为N = 5的情况下:

We tried to work through this problem for the case of N = 5:

x = [1, 2, 3, 4, 5]

首先,交换元件4和5:

First, swap elements 4 and 5:

x = [1, 2, 3, 5, 4]

然后交换3和5:

Then swap 3 and 5:

x = [1, 2, 4, 5, 3]

接着3和4:

Then 3 and 4:

x = [1, 2, 5, 4, 3]

本来我们想用两个指数,九和JX,可能是一个可能的解决方案。是这样的:

Originally we thought using two indices, ix and jx, might be a possible solution. Something like:

ix = 0;
jx = 0;

for(;;)
{
    ++ ix;

    if(ix >= N)
    {
        ix = 0;
        ++ jx;

        if(jx >= N)
        {
            break; // We have got to an exit condition, but HAVENT got all permutations
        }
    }

    swap elements at positions ix and jx

    print out the elements
}

这适用于当n = 3,但是它并没有更高的N.工作,我们认为,这种做法可能是沿着正确的方向。我们试图延长到3索引中使用的方法,由于某种原因,我们认为这可能是该溶液:使用第三索引标记向量中的位置的索引九开始或结束。但是,我们卡住了,并决定要求SO社会征求意见。

This works for the case where N = 3. However it doesn't work for higher N. We think that this sort of approach might be along the right lines. We were trying to extend to a method where 3 indexes are used, for some reason we think that might be the solution: Using a 3rd index to mark a position in the vector where the index ix starts or ends. But we got stuck, and decided to ask the SO community for advice.

推荐答案

要做到这一点的方法之一是,第一个字符电子

One way to do this is to, for the first character e:

在接下来的元素首先递归 然后,对每个元素 E2 电子: 交换电子 E2 然后递归的下一个元素 ,并撤消掉 First recurse on the next element Then, for each element e2 after e: Swap e and e2 Then recurse on the next element And undo the swap

伪code:

permutation(input, 0)

permutation(char[] array, int start)
    if (start == array.length)
        print array

    for (int i = start; i < array.length; i++)
        swap(array[start], array[i])
        permutation(array, start+1)
        swap(array[start], array[i])

使用此功能的主要呼叫,它将尝试的每个字符在第一位置,然后递归。简单地遍历所有的人物在这里工作,因为我们撤消每个交换算账,递归调用返回后,我们保证是回到了起点。

With the main call of this function, it will try each character in the first position and then recurse. Simply looping over all the characters works here because we undo each swap afterwards, so after the recursive call returns, we're guaranteed to be back where we started.

和然后,对每个那些递归调用的,它试图在第二位置的每个其余的字符。等等。

And then, for each of those recursive calls, it tries each remaining character in the second position. And so on.

Java的现场演示。