Find the index of a given permutation in the sorted list of the permutations of a given string

后端 未结 6 678
轻奢々
轻奢々 2020-11-29 04:29

We\'re given a string and a permutation of the string.

For example, an input string sandeep and a permutation psdenae.

Find the pos

6条回答
  •  长情又很酷
    2020-11-29 05:32

    Building off @Algorithmist 's answer, and his comment to his answer, and using the principle discussed in this post for when there are repeated letters, I made the following algorithm in JavaScript that works for all letter-based words even with repeated letter instances.

    function anagramPosition(string) {
      var index = 1;
      var remainingLetters = string.length - 1;
      var frequencies = {};
      var splitString = string.split("");
      var sortedStringLetters = string.split("").sort();
    
      sortedStringLetters.forEach(function(val, i) {
        if (!frequencies[val]) {
          frequencies[val] = 1;
        } else {
          frequencies[val]++;
        }
      })
    
      function factorial(coefficient) {
        var temp = coefficient;
        var permutations = coefficient;
        while (temp-- > 2) {
          permutations *= temp;
        }
        return permutations;
      }
    
      function getSubPermutations(object, currentLetter) {
        object[currentLetter]--;
        var denominator = 1;
        for (var key in object) {
          var subPermutations = factorial(object[key]);
          subPermutations !== 0 ? denominator *= subPermutations : null;
        }
        object[currentLetter]++;
        return denominator;
      }
    
      var splitStringIndex = 0;
      while (sortedStringLetters.length) {
        for (var i = 0; i < sortedStringLetters.length; i++) {
          if (sortedStringLetters[i] !== splitString[splitStringIndex]) {
            if (sortedStringLetters[i] !== sortedStringLetters[i+1]) {
              var permutations = factorial(remainingLetters);
              index += permutations / getSubPermutations(frequencies, sortedStringLetters[i]);
            } else {
              continue;
            }
          } else {
            splitStringIndex++;
            frequencies[sortedStringLetters[i]]--;
            sortedStringLetters.splice(i, 1);
            remainingLetters--;
            break;
          }
        }
      }
      return index;
    }
    
    anagramPosition("ARCTIC") // => 42
    

    I didn't comment the code but I did try to make the variable names as explanatory as possible. If you run it through a debugger process using your dev tools console and throw in a few console.logs you should be able to see how it uses the formula in the above-linked S.O. post.

提交回复
热议问题