在javascript中更简单地实现Steinhaus-Johnson-Trotter算法

时间:2016-03-26 00:01:17

标签: javascript algorithm permutation

我知道有很简单的方法来生成字符串中所有可能的字符排列,尤其是递归,但我发现了Steinhaus Johnson Trotter算法如何工作的非常清晰的描述here,并希望实现它忠实于Javascript。

为此,我为字符串中的每个字符创建了一个对象,其中“direction”属性可以从左向右更改。

代码可以工作,但就像,不可思议的长而且非常丑陋(例如,使用嵌套的if语句)。我会理解如何简化它。

function permutations(string) {
    var letterArray = [];
    var permutSolution = [string];

    //Create objects for each character with initial position value and direction:
    function letter(char, pos, dir) {
        this.character = char;
        this.position = pos;
        this.direction = dir;
    }
    for (i = 0; i < string.length; i++) {
        var newLetterObj = new letter(string[i], i, 'left');
        letterArray.push(newLetterObj);
    }

    //function to identify the highest mobile character
    function findHighestMC(value) {
        return value.position == i;
    }

    //change the direction of characters with a higher position value than the current highest mobile character
    function changeHigherMCDirection(element, index, array) {
        if (element.position > i && element.direction == 'left') {
            element.direction = 'right';
        }
        else if (element.position > i && element.direction == 'right') {
            element.direction = 'left';
        }
    }

    //run the algorithm through the input string
    for (i = string.length -1; i > -1; i--) {
        var highestMC = letterArray.filter(findHighestMC)[0]; //extract object from array
        var highestMCIndex = letterArray.indexOf(highestMC);
        if (highestMC.direction == 'left' && letterArray[highestMCIndex - 1] !== undefined && letterArray[highestMCIndex - 1].position < letterArray[highestMCIndex].position) {
            var swap = letterArray[highestMCIndex];
            letterArray[highestMCIndex] = letterArray[highestMCIndex - 1];
            letterArray[highestMCIndex - 1] = swap;
            var newPermut = letterArray.map(function(obj) {return obj.character;}).join('');
            permutSolution.push(newPermut);
            if (i == string.length - 1) {
                i++;
            }
            else if (i < string.length - 1) {
                letterArray.forEach(changeHigherMCDirection);
                i = string.length;
            }
        }
        else if (highestMC.direction == 'right' && letterArray[highestMCIndex + 1] !== undefined && letterArray[highestMCIndex + 1].position < letterArray[highestMCIndex].position) {
            var swap = letterArray[highestMCIndex];
            letterArray[highestMCIndex] = letterArray[highestMCIndex + 1];
            letterArray[highestMCIndex + 1] = swap;
            var newPermut = letterArray.map(function(obj) {return obj.character;}).join('');
            permutSolution.push(newPermut);
            if (i == string.length - 1) {
                i++;
            }
            else if (i < string.length - 1) {
                letterArray.forEach(changeHigherMCDirection);
                i = string.length;
            }
        }
    }

    //remove duplicates from solution in case letters in input string aren't all unique
    function deDupe (element, index, array) {
        return array.indexOf(element) == index;
    }
    permutSolution = permutSolution.filter(deDupe);

    return permutSolution;
}
console.log(permutations('abcd'))

0 个答案:

没有答案
相关问题