algorithm - 파이썬 - 빠른 순열-> 순열-> 순열 매핑 알고리즘




파이썬 조합 (7)

n 요소의 순열을 설명하려면 첫 번째 요소가 끝나는 위치에 대해 n 개의 가능성이 있으므로 0과 n-1 사이의 숫자로 설명 할 수 있습니다. 다음 요소가 끝나는 위치에 대해 n-1 개의 가능성이 있으므로 0과 n-2 사이의 숫자로 설명 할 수 있습니다.
당신이 n 개의 숫자를 가질 때까지 등등.

n = 5의 예로서, abcdecaebd 가져 오는 순열을 고려하십시오.

  • 첫 번째 요소 인 a 는 두 번째 위치에서 끝나기 때문에 인덱스 1을 할당합니다.
  • b 는 인덱스 3이 될 네 번째 위치에서 끝나지만 나머지 세 번째 것이므로 2로 지정합니다.
  • c 는 항상 0 인 첫 번째 나머지 위치에서 끝납니다.
  • d 는 마지막 남은 위치에서 끝나며 (나머지 두 위치 중에서) 1 입니다.
  • e0으로 인덱싱 된 유일한 나머지 위치에서 끝납니다.

그래서 우리는 인덱스 시퀀스 {1, 2, 0, 1, 0}을가 집니다.

이제는 이진수로 'xyz'가 z + 2y + 4x를 의미한다는 것을 알고 있습니다. 10 진수의 경우,
그것은 z + 10y + 100x입니다. 각 자릿수에 약간의 가중치가 곱해지고 결과가 합산됩니다. 무게의 명백한 패턴은 물론 무게가 w = b ^ k인데, b는 숫자의 밑수, k는 숫자의 지수입니다. (필자는 항상 오른쪽에서부터 숫자를 계산할 것이고 가장 오른쪽 숫자는 인덱스 0부터 시작합니다. 마찬가지로 '첫 번째'숫자에 대해서 말하면 오른쪽 끝을 의미합니다.)

숫자에 대한 가중치가이 패턴을 따르는 이유는 0에서 k까지의 숫자로 표시 될 수있는 가장 높은 숫자는 숫자 k + 1만을 사용하여 표현할 수있는 가장 낮은 숫자보다 정확히 1 낮아야한다는 것입니다. 이진수에서는 0111이 1000보다 작아야합니다. 십진수에서는 099999가 100000보다 작은 숫자 여야합니다.

변수 기반으로 인코딩
후속 숫자 사이의 간격은 정확하게 1입니다 중요한 규칙입니다. 이를 실현하기 위해 인덱스 시퀀스를 가변 기준 번호로 나타낼 있습니다. 각 자릿수에 대한 기준은 해당 자릿수의 다른 가능성의 양입니다. 10 진수의 경우 각 숫자에는 10 가지 가능성이 있습니다. 우리 시스템의 경우 오른쪽 자리는 1 가능성을 가지며 가장 왼쪽 숫자는 n 가능성을 갖습니다. 그러나 가장 오른쪽 숫자 (우리 시퀀스의 마지막 숫자)가 항상 0이기 때문에 우리는 그것을 버립니다. 그건 우리가 2에서 n까지 2 루수로 남아 있다는 것을 의미합니다. 일반적으로 k 번째 자릿수는 기본 b [k] = k + 2입니다. 자릿수 k에 대해 허용되는 최대 값은 h [k] - 1 = k + 1입니다.

자릿수의 가중치 w [k]에 대한 규칙은 i = 0에서 i = k로가는 h [i] * w [i]의 합이 1 * w [k + 1]과 같아야한다는 것을 의미합니다. 반복적으로, w [k + 1] = w [k] + h [k] * w [k] = w [k] * (h [k] + 1). 첫 번째 가중치 w [0]은 항상 1이어야합니다. 거기에서 시작하여 다음 값을 갖습니다.

k    h[k] w[k]    

0    1    1  
1    2    2    
2    3    6    
3    4    24   
...  ...  ...
n-1  n    n!  

(일반적인 관계 w [k-1] = k!는 유도에 의해 쉽게 증명된다.)

우리의 시퀀스를 변환함으로써 얻을 수있는 수는 s [k] * w [k]의 합이며, k는 0에서 n-1까지입니다. 여기서 s [k]는 시퀀스의 k 번째 (오른쪽에서 시작, 0) 요소입니다. 예를 들어, 앞에서 언급 한 것처럼 {1, 2, 0, 1, 0}을 제거하고 {1, 2, 0, 1} . 우리 합계는 1 * 1 + 0 * 2 + 2 * 6 + 1 * 24 = 37 입니다.

모든 인덱스에 대해 최대 순위를 취하면 {4, 3, 2, 1, 0}이되며 119로 변환됩니다. 숫자 인코딩의 가중치는 건너 뛰지 않도록 선택했기 때문에 모든 숫자, 0에서 119까지의 모든 숫자가 유효합니다. 정확하게 120 개가 있는데, n 개입니다. 우리의 예에서 n = 5인데, 정확히 다른 순열의 수. 따라서 인코딩 된 숫자가 가능한 모든 순열을 지정하는 것을 볼 수 있습니다.

변수 기반의 디코딩
디코딩은 2 진 또는 10 진수로 변환하는 것과 유사합니다. 일반적인 알고리즘은 다음과 같습니다.

int number = 42;
int base = 2;
int[] bits = new int[n];

for (int k = 0; k < bits.Length; k++)
{
    bits[k] = number % base;
    number = number / base;
}

우리의 가변 기지 번호 :

int n = 5;
int number = 37;

int[] sequence = new int[n - 1];
int base = 2;

for (int k = 0; k < sequence.Length; k++)
{
    sequence[k] = number % base;
    number = number / base;

    base++; // b[k+1] = b[k] + 1
}

이렇게하면 37을 {1, 2, 0, 1} (이 코드 예제에서는 sequence{1, 0, 2, 1} 이 되겠지만, 적절하게 색인화하는 한 ...)로 올바르게 디코딩합니다. 우리는 원래의 시퀀스 {1, 2, 0, 1, 0}을 되찾기 위해 오른쪽 끝에 0을 추가하기 만하면됩니다. 마지막 요소는 항상 새로운 위치에 대해 하나의 가능성을 가지고 있습니다.

인덱스 시퀀스를 사용하여 목록을 옮기기
아래의 알고리즘을 사용하여 특정 인덱스 순서에 따라 목록을 바꿀 수 있습니다. 불운하게도 O (n²) 알고리즘입니다.

int n = 5;
int[] sequence = new int[] { 1, 2, 0, 1, 0 };
char[] list = new char[] { 'a', 'b', 'c', 'd', 'e' };
char[] permuted = new char[n];
bool[] set = new bool[n];

for (int i = 0; i < n; i++)
{
    int s = sequence[i];
    int remainingPosition = 0;
    int index;

    // Find the s'th position in the permuted list that has not been set yet.
    for (index = 0; index < n; index++)
    {
        if (!set[index])
        {
            if (remainingPosition == s)
                break;

            remainingPosition++;
        }
    }

    permuted[index] = list[i];
    set[index] = true;
}

순열의 일반적인 표현
일반적으로 순열은 직관적으로 우리가 한 것처럼 직관적으로 표현하지 않지만 단순히 순열이 적용된 후 각 요소의 절대 위치로 나타냅니다. abcde 에서 caebd 예제 {1, 2, 0, 1, 0}은 일반적으로 {1, 3, 0, 4, 2}로 표현됩니다. 0에서 4까지 (또는 일반적으로 0에서 n-1까지)의 각 인덱스는이 표현에서 정확히 한 번 발생합니다.

이 형식으로 순열을 적용하는 것은 쉽습니다.

int[] permutation = new int[] { 1, 3, 0, 4, 2 };

char[] list = new char[] { 'a', 'b', 'c', 'd', 'e' };
char[] permuted = new char[n];

for (int i = 0; i < n; i++)
{
    permuted[permutation[i]] = list[i];
}

그것을 뒤집는 것은 매우 유사합니다 :

for (int i = 0; i < n; i++)
{
    list[i] = permuted[permutation[i]];
}

우리의 표현에서 일반적인 표현으로의 변환
우리의 알고리즘을 인덱스 시퀀스를 사용하여리스트를 치환하고이를 아이디 순열 {0, 1, 2, ..., n-1}에 적용하면, 일반적인 형태로 표현 된 순열을 얻는다 . (이 예에서는 {2, 0, 4, 1, 3} ).

비 반전 된 전치 인수를 얻기 위해, 우리는 방금 나타낸 순열 알고리즘을 적용한다.

int[] identity = new int[] { 0, 1, 2, 3, 4 };
int[] inverted = { 2, 0, 4, 1, 3 };
int[] normal = new int[n];

for (int i = 0; i < n; i++)
{
    normal[identity[i]] = list[i];
}

또는 역전 치법을 사용하여 순열을 직접 적용 할 수 있습니다.

char[] list = new char[] { 'a', 'b', 'c', 'd', 'e' };
char[] permuted = new char[n];

int[] inverted = { 2, 0, 4, 1, 3 };

for (int i = 0; i < n; i++)
{
    permuted[i] = list[inverted[i]];
}

공통 형태의 순열을 다루기위한 모든 알고리즘은 O (n)이고, 순열을 적용하는 것은 O (n²)이다. 순열을 여러 번 적용해야하는 경우 먼저 일반 표현으로 변환하십시오.

나는 n 개의 원소를 가지고있다. 예를 들어, 7 개의 요소 인 1234567을 가정 해 봅시다. 7이 있다는 것을 알고 있습니다! = 7 개의 요소가 가능한 5040 개의 순열

두 가지 기능으로 구성된 빠른 알고리즘이 필요합니다.

f (숫자)는 0에서 5039 사이의 숫자를 고유 순열로 매핑하고,

f '(순열)은 순열을 생성 된 번호로 다시 매핑합니다.

나는 각 순열이 그것의 자신의 고유 번호를 가지고 있으면서, 수와 순열 사이의 대응에 신경 쓰지 않는다.

예를 들어, 나는 함수를 가질 수 있습니다.

f(0) = '1234567'
f'('1234567') = 0

가장 빠른 알고리즘은 모든 순열을 열거하고 양방향으로 룩업 테이블을 생성하여 테이블이 생성되면 f (0)은 O (1)이고 f ( '1234567')는 a 문자열에 대한 조회. 그러나 이것은 특히 n이 커질 때 배가 고프다.

누구든지 신속하고 메모리 단점없이 작동하는 다른 알고리즘을 제안 할 수 있습니까?


각 요소는 7 가지 위치 중 하나에있을 수 있습니다. 하나의 요소의 위치를 ​​설명하려면 세 비트가 필요합니다. 즉, 모든 요소의 위치를 ​​32 비트 값으로 저장할 수 있습니다. 이 표현은 모든 요소가 같은 위치에있을 수도 있기 때문에 효율적이지 않습니다.하지만 비트 마스킹은 상당히 빨라야합니다.

그러나 8 개 이상의 직책을 사용하면 더 멋진 뭔가가 필요합니다.


나는 나의 이전 대답 (삭제 된)에서 성급했다, 나는 실제 대답을 가지고있다. 그것은 유사한 개념, factoradic 의해 제공되며, 순열과 관련이 있습니다 (조합에 관련된 나의 대답, 나는 그 혼란에 대해 사과합니다). 나는 위키피디아 링크를 게시하는 것을 싫어하지만, 내가 잠시 전에했던 필사본은 어떤 이유에서인지 할 수 없다. 그래서, 나중에 요청하면 확장 할 수 있습니다.


문제 해결됨. 그러나, 나는 아직도 당신이이 해가 지난 후에도 해결책이 필요하다는 것을 확신하지 못합니다. LOL, 방금이 사이트에 가입했습니다. Java Permutation Class를 확인하십시오. 인덱스를 기반으로 심볼 순열을 얻거나 심볼 순열을 부여한 다음 인덱스를 얻을 수 있습니다.

여기에 선교 학급이 있습니다.

/**
 ****************************************************************************************************************
 * Copyright 2015 Fred Pang [email protected]
 ****************************************************************************************************************
 * A complete list of Permutation base on an index.
 * Algorithm is invented and implemented by Fred Pang [email protected]
 * Created by Fred Pang on 18/11/2015.
 ****************************************************************************************************************
 * LOL this is my first Java project. Therefore, my code is very much like C/C++. The coding itself is not
 * very professional. but...
 *
 * This Permutation Class can be use to generate a complete list of all different permutation of a set of symbols.
 * nPr will be n!/(n-r)!
 * the user can input       n = the number of items,
 *                          r = the number of slots for the items,
 *                          provided n >= r
 *                          and a string of single character symbols
 *
 * the program will generate all possible permutation for the condition.
 *
 * Say if n = 5, r = 3, and the string is "12345", it will generate sll 60 different permutation of the set
 * of 3 character strings.
 *
 * The algorithm I used is base on a bin slot.
 * Just like a human or simply myself to generate a permutation.
 *
 * if there are 5 symbols to chose from, I'll have 5 bin slot to indicate which symbol is taken.
 *
 * Note that, once the Permutation object is initialized, or after the constructor is called, the permutation
 * table and all entries are defined, including an index.
 *
 * eg. if pass in value is 5 chose 3, and say the symbol string is "12345"
 * then all permutation table is logically defined (not physically to save memory).
 * It will be a table as follows
 *  index  output
 *      0   123
 *      1   124
 *      2   125
 *      3   132
 *      4   134
 *      5   135
 *      6   143
 *      7   145
 *      :     :
 *      58  542
 *      59  543
 *
 * all you need to do is call the "String PermGetString(int iIndex)" or the "int[] PermGetIntArray(int iIndex)"
 * function or method with an increasing iIndex, starting from 0 to getiMaxIndex() - 1. It will return the string
 * or the integer array corresponding to the index.
 *
 * Also notice that in the input string is "12345" of  position 01234, and the output is always in accenting order
 * this is how the permutation is generated.
 *
 * ***************************************************************************************************************
 * ====  W a r n i n g  ====
 * ***************************************************************************************************************
 *
 * There is very limited error checking in this class
 *
 * Especially the  int PermGetIndex(int[] iInputArray)  method
 * if the input integer array contains invalid index, it WILL crash the system
 *
 * the other is the string of symbol pass in when the object is created, not sure what will happen if the
 * string is invalid.
 * ***************************************************************************************************************
 *
 */
public class Permutation
{
    private boolean bGoodToGo = false;      // object status
    private boolean bNoSymbol = true;
    private BinSlot slot;                   // a bin slot of size n (input)
    private int nTotal;                     // n number for permutation
    private int rChose;                     // r position to chose
    private String sSymbol;                 // character string for symbol of each choice
    private String sOutStr;
    private int iMaxIndex;                  // maximum index allowed in the Get index function
    private int[] iOutPosition;             // output array
    private int[] iDivisorArray;            // array to do calculation

    public Permutation(int inCount, int irCount, String symbol)
    {
        if (inCount >= irCount)
        {
            // save all input values passed in
            this.nTotal = inCount;
            this.rChose = irCount;
            this.sSymbol = symbol;

            // some error checking
            if (inCount < irCount || irCount <= 0)
                return;                                 // do nothing will not set the bGoodToGo flag

            if (this.sSymbol.length() >= inCount)
            {
                bNoSymbol = false;
            }

            // allocate output storage
            this.iOutPosition = new int[this.rChose];

            // initialize the bin slot with the right size
            this.slot = new BinSlot(this.nTotal);

            // allocate and initialize divid array
            this.iDivisorArray = new int[this.rChose];

            // calculate default values base on n & r
            this.iMaxIndex = CalPremFormula(this.nTotal, this.rChose);

            int i;
            int j = this.nTotal - 1;
            int k = this.rChose - 1;

            for (i = 0; i < this.rChose; i++)
            {
                this.iDivisorArray[i] = CalPremFormula(j--, k--);
            }
            bGoodToGo = true;       // we are ready to go
        }
    }

    public String PermGetString(int iIndex)
    {
        if (!this.bGoodToGo) return "Error: Object not initialized Correctly";
        if (this.bNoSymbol) return "Error: Invalid symbol string";
        if (!this.PermEvaluate(iIndex)) return "Invalid Index";

        sOutStr = "";
        // convert string back to String output
        for (int i = 0; i < this.rChose; i++)
        {
            String sTempStr = this.sSymbol.substring(this.iOutPosition[i], iOutPosition[i] + 1);
            this.sOutStr = this.sOutStr.concat(sTempStr);
        }
        return this.sOutStr;
    }

    public int[] PermGetIntArray(int iIndex)
    {
        if (!this.bGoodToGo) return null;
        if (!this.PermEvaluate(iIndex)) return null ;
        return this.iOutPosition;
    }

    // given an int array, and get the index back.
    //
    //  ====== W A R N I N G ======
    //
    // there is no error check in the array that pass in
    // if any invalid value in the input array, it can cause system crash or other unexpected result
    //
    // function pass in an int array generated by the PermGetIntArray() method
    // then return the index value.
    //
    // this is the reverse of the PermGetIntArray()
    //
    public int PermGetIndex(int[] iInputArray)
    {
        if (!this.bGoodToGo) return -1;
        return PermDoReverse(iInputArray);
    }


    public int getiMaxIndex() {
    return iMaxIndex;
}

    // function to evaluate nPr = n!/(n-r)!
    public int CalPremFormula(int n, int r)
    {
        int j = n;
        int k = 1;
        for (int i = 0; i < r; i++, j--)
        {
            k *= j;
        }
        return k;
    }


//  PermEvaluate function (method) base on an index input, evaluate the correspond permuted symbol location
//  then output it to the iOutPosition array.
//
//  In the iOutPosition[], each array element corresponding to the symbol location in the input string symbol.
//  from location 0 to length of string - 1.

    private boolean PermEvaluate(int iIndex)
    {
        int iCurrentIndex;
        int iCurrentRemainder;
        int iCurrentValue = iIndex;
        int iCurrentOutSlot;
        int iLoopCount;

        if (iIndex >= iMaxIndex)
            return false;

        this.slot.binReset();               // clear bin content
        iLoopCount = 0;
        do {
            // evaluate the table position
            iCurrentIndex = iCurrentValue / this.iDivisorArray[iLoopCount];
            iCurrentRemainder = iCurrentValue % this.iDivisorArray[iLoopCount];

            iCurrentOutSlot = this.slot.FindFreeBin(iCurrentIndex);     // find an available slot
            if (iCurrentOutSlot >= 0)
                this.iOutPosition[iLoopCount] = iCurrentOutSlot;
            else return false;                                          // fail to find a slot, quit now

            this.slot.setStatus(iCurrentOutSlot);                       // set the slot to be taken
            iCurrentValue = iCurrentRemainder;                          // set new value for current value.
            iLoopCount++;                                               // increase counter
        } while (iLoopCount < this.rChose);

        // the output is ready in iOutPosition[]
        return true;
    }

    //
    // this function is doing the reverse of the permutation
    // the input is a permutation and will find the correspond index value for that entry
    // which is doing the opposit of the PermEvaluate() method
    //
    private int PermDoReverse(int[] iInputArray)
    {
        int iReturnValue = 0;
        int iLoopIndex;
        int iCurrentValue;
        int iBinLocation;

        this.slot.binReset();               // clear bin content

        for (iLoopIndex = 0; iLoopIndex < this.rChose; iLoopIndex++)
        {
            iCurrentValue = iInputArray[iLoopIndex];
            iBinLocation = this.slot.BinCountFree(iCurrentValue);
            this.slot.setStatus(iCurrentValue);                          // set the slot to be taken
            iReturnValue = iReturnValue + iBinLocation * this.iDivisorArray[iLoopIndex];
        }
        return iReturnValue;
    }


    /*******************************************************************************************************************
     *******************************************************************************************************************
     * Created by Fred on 18/11/2015.   [email protected]
     *
     * *****************************************************************************************************************
     */
    private static class BinSlot
    {
        private int iBinSize;       // size of array
        private short[] eStatus;    // the status array must have length iBinSize

        private BinSlot(int iBinSize)
        {
            this.iBinSize = iBinSize;               // save bin size
            this.eStatus = new short[iBinSize];     // llocate status array
        }

        // reset the bin content. no symbol is in use
        private void binReset()
        {
            // reset the bin's content
            for (int i = 0; i < this.iBinSize; i++) this.eStatus[i] = 0;
        }

        // set the bin position as taken or the number is already used, cannot be use again.
        private void  setStatus(int iIndex) { this.eStatus[iIndex]= 1; }

        //
        // to search for the iIndex th unused symbol
        // this is important to search through the iindex th symbol
        // because this is how the table is setup. (or the remainder means)
        // note: iIndex is the remainder of the calculation
        //
        // for example:
        // in a 5 choose 3 permutation symbols "12345",
        // the index 7 item (count starting from 0) element is "1 4 3"
        // then comes the index 8, 8/12 result 0 -> 0th symbol in symbol string = '1'
        // remainder 8. then 8/3 = 2, now we need to scan the Bin and skip 2 unused bins
        //              current the bin looks 0 1 2 3 4
        //                                    x o o o o     x -> in use; o -> free only 0 is being used
        //                                      s s ^       skipped 2 bins (bin 1 and 2), we get to bin 3
        //                                                  and bin 3 is the bin needed. Thus symbol "4" is pick
        // in 8/3, there is a remainder 2 comes in this function as 2/1 = 2, now we have to pick the empty slot
        // for the new 2.
        // the bin now looks 0 1 2 3 4
        //                   x 0 0 x 0      as bin 3 was used by the last value
        //                     s s   ^      we skip 2 free bins and the next free bin is bin 4
        //                                  therefor the symbol "5" at the symbol array is pick.
        //
        // Thus, for index 8  "1 4 5" is the symbols.
        //
        //
        private int FindFreeBin(int iIndex)
        {
            int j = iIndex;

            if (j < 0 || j > this.iBinSize) return -1;               // invalid index

            for (int i = 0; i < this.iBinSize; i++)
            {
                if (this.eStatus[i] == 0)       // is it used
                {
                    // found an empty slot
                    if (j == 0)                 // this is a free one we want?
                        return i;               // yes, found and return it.
                    else                        // we have to skip this one
                        j--;                    // else, keep looking and count the skipped one
                }
            }
            assert(true);           // something is wrong
            return -1;              // fail to find the bin we wanted
        }

        //
        // this function is to help the PermDoReverse() to find out what is the corresponding
        // value during should be added to the index value.
        //
        // it is doing the opposite of int FindFreeBin(int iIndex) method. You need to know how this
        // FindFreeBin() works before looking into this function.
        //
        private int BinCountFree(int iIndex)
        {
            int iRetVal = 0;
            for (int i = iIndex; i > 0; i--)
            {
                if (this.eStatus[i-1] == 0)       // it is free
                {
                    iRetVal++;
                }
            }
            return iRetVal;
        }
    }
}
// End of file - Permutation.java

클래스를 사용하는 방법을 보여주는 기본 클래스가 있습니다.

/*
 * copyright 2015 Fred Pang
 *
 * This is the main test program for testing the Permutation Class I created.
 * It can be use to demonstrate how to use the Permutation Class and its methods to generate a complete
 * list of a permutation. It also support function to get back the index value as pass in a permutation.
 *
 * As you can see my Java is not very good. :)
 * This is my 1st Java project I created. As I am a C/C++ programmer for years.
 *
 * I still have problem with the Scanner class and the System class.
 * Note that there is only very limited error checking
 *
 *
 */

import java.util.Scanner;

public class Main
{
    private static Scanner scanner = new Scanner(System.in);

    public static void main(String[] args)
    {
        Permutation perm;       // declear the object
        String sOutString = "";
        int nCount;
        int rCount;
        int iMaxIndex;

        // Get user input
        System.out.println("Enter n: ");
        nCount = scanner.nextInt();

        System.out.println("Enter r: ");
        rCount = scanner.nextInt();

        System.out.println("Enter Symbol: ");
        sOutString = scanner.next();

        if (sOutString.length() < rCount)
        {
            System.out.println("String too short, default to numbers");
            sOutString = "";
        }

        // create object with user requirement
        perm = new Permutation(nCount, rCount, sOutString);

        // and print the maximum count
        iMaxIndex = perm.getiMaxIndex();
        System.out.println("Max count is:" + iMaxIndex);

        if (!sOutString.isEmpty())
        {
            for (int i = 0; i < iMaxIndex; i++)
            {   // print out the return permutation symbol string
                System.out.println(i + " " + perm.PermGetString(i));
            }
        }
        else
        {
            for (int i = 0; i < iMaxIndex; i++)
            {
                System.out.print(i + " ->");

                // Get the permutation array
                int[] iTemp = perm.PermGetIntArray(i);

                // print out the permutation
                for (int j = 0; j < rCount; j++)
                {
                    System.out.print(' ');
                    System.out.print(iTemp[j]);
                }

                // to verify my PermGetIndex() works. :)
                if (perm.PermGetIndex(iTemp)== i)
                {
                    System.out.println(" .");
                }
                else
                {   // oops something is wrong :(
                    System.out.println(" ***************** F A I L E D *************************");
                    assert(true);
                    break;
                }
            }
        }
    }
}
//
// End of file - Main.java

재미있게 보내십시오. :)


이것에 관해 쓰여진 책이 있습니다. 미안하지만, 나는 그 이름을 기억하지 못한다. (아마 위키피디아에서 찾을 수있을 것이다.) 하지만 어쨌든 저는 열거 형 시스템의 파이썬 구현을 작성했습니다 : http://kks.cabal.fi/Kombinaattori 중 일부는 핀란드어이지만 코드와 이름 변수를 복사합니다 ...


이것은 J 의 내장 함수입니다.

   A. 1 2 3 4 5 6 7
0
   0 A. 1 2 3 4 5 6 7
1 2 3 4 5 6 7

   ?!7
5011
   5011 A. 1 2 3 4 5 6 7
7 6 4 5 1 3 2
   A. 7 6 4 5 1 3 2
5011

참으로 흥미로운 질문입니다!

모든 요소가 숫자 인 경우 문자열에서 실제 숫자로 변환하는 것이 좋습니다. 그런 다음 순열을 순서대로 배열하여 모든 순열을 정렬하고 배열에 배치 할 수 있습니다. 그 후에는 다양한 검색 알고리즘을 사용할 수 있습니다.





combinatorics