How can I configure this Javascript code to print all permutations of sentences on every line of input?

So, for example, if I have this input:

I am the man

      

I want to come back:

I am the man
I the man
I man
I the
I am
am the man
am man
am the
the man
man
man I
man I am
etc.

      

This is what I have so far for the first 20 sentences of input

            for (var i = 0; i < 20; i++) {
                var currWords = data[i].DisplayName.replace(/[^\x00-\x7F]/g, "").replace(/\(/g, "").replace(/\-/g, " ").replace(/\)/g, "").replace(/\*/g, "").toLowerCase().split(/\s+/g);

                for (var j = 0; j < currWords.length; j++) {
                    var currString = "";
                    for (var k = j; k < currWords.length; k++) {
                        currString += (currWords[k] + " ");
                    }
                    console.log(currString);
                }
            }

      

I just want them to be printed so I can copy them for something else. So far, this is only getting things going forward and I can't think of an easy way to make the best suggestion possible. What do you recommend?

+3


source to share


2 answers


After looking at your own question, I think you can adapt the heap algorithm

I am writing and adapting this to es6 with the only change I am building a string with bitCheck statements ...



<!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>I am the man</title>
</head>
<body>
  <div id="output"></div>
  <script>
    p = m => {
      var a = m.split(' '),
      s = new Set(), l = a.length, ms, 
      b = (n=l) => {
        if (n == 1) {
          for ( let i = 1; i < 2**l; i++){
            ms = '';
            for ( let y = 0; y < l; y++){
              if (i & (1 << y)){
                ms += a[y]+" ";
              }
            }
          s.add(ms.trim());
          }
      } 
        else {
          for (let i=0;i<n;i++) {
            b(n - 1);
            [a[(n%2)*i],a[n-1]] = [a[n-1],a[(n%2)*i]];
          }
        }
      }
      b();
      return s;
    }
    test = p("I am the man")
    test.forEach(e => output.innerHTML += e + '<br>');
  </script>
</body>
</html>
      

Run codeHide result


+1


source


Well his question about creating a permutation might be a general question as well, not javascript specific or a specific proposal, there might be multiple approaches, let ma explain one of them, what can I think in the short term

SO, your sentence "I am human", having four words, is to first split them into an array like

var words = "I am the man".split(" ")

      

so your array has words ["I", "am", "the", "man"]

and length

is 4

because you have 4 words. Now, how about creating a permutation of these numbers ( 1234

) and each result use each digit as the index of the word array and the union? embarrassed? Let me explain.

What if we can create an array like

[1, 2, 3, 4, 12, 13, 14, 21, 23, 24, 41, 42, 43, 123, 124, ...., 4321]

and then from each number you can build a sentence:

eg:

1: "I"
4: "man"
43: "man the"
..
..
4321: "man the am I"

      

(If you have a question about how to generate these strings from numbers, I'll clarify that later, for now don't forget that you already have an array of words)

Now the question may arise, what if we compute the permutation over this record 9

? For the 9

maximum value would be 987654321

(since we all think of as a number), so in all cases I prefer to build an array instead of numbers, because ultimately we need to split all the numbers and extract from the index from the word array.

so instead of

[1, 2, 3, 4, 12, 13, 14, 21, 23, 24, 41, 42, 43, 123, 124, ...., 4321]

I prefer

[ [1], [2], [3], [4], [1, 2], [1, 3],..., [3, 4, 1],........., [4, 3, 2, 1] ]

because the number can go out of bounds 9

and we can deal with it easily.

So now the question is how will you construct the array of numbers (trust me, this is the most important thing, your output is just a logic map)

So if we start with an array, initializing it like this: [[1], [2], [3], [4]]

to length, so we start at level 2,

we will loop through from 1 to length (that is, from 1 to 4), and at each iteration we will iterate over each array and check that the array contains the current number, or not, unless we slice the array and push the current number into start and then revert it to the main results array. we will also pass each array of digits so that we don't have to look at the whole array, for level 1 both will be the same, so we will make a copy of that file slice()

and we will return the array for the current digit as well

function processEachDigit(length, mainArray, lastDigitArray) {
    var currDigitArray = [];
    var n;
    for (n = 1; n <= length; n++) {
        for (idx = 0; idx < lastDigitArray.length; idx++) {
            var eachArray = lastDigitArray[idx];
            if (!eachArray.includes(n)) {
                var newArr = eachArray.slice();
                newArr.unshift(n)
                mainArray.push(newArr);
                currDigitArray.push(newArr)
            }
        }
    }
return currDigitArray;
}

      



so the first time we have

mainArray = [[1], [2], [3], [4]] //will initialize through a loop

and

currDigitArray  = mainArray.slice()
//as we will keep update mainArray we cannot use the same reference

      

and we will call it like

processEachDigit(words.length, mainArray, currDigitArray)

      

so mainArray was

[[1], [2], [3], [4]]

and he became

[[1], [2], [3], [4], [1, 2], [1,3], ......., [4,2], [4,3]]

and it returns an array of the second digit element, i.e.

[[1,2], [1, 3], [1, 4], [2, 1], [2, 3]......., [4,2], [4,3]]

so we will call with the second digital array to build a 3-digit array, and then pass the 3rd bit array to build the 4th digital array.

Now do we really need to build an array with one digit first? NOT.

passing an empty array of an array will create it since no element will be found there, so we all need to just initialize the main array as an empty array and the current array of digits as an empty array of the array, I just said slice()

and that's it to explain what we are trying to do.

Here we go

function getPermutationArray(L) {
var mainArr = [];
var n;
var currDigitArr = [[]];
    for(n=1;n<=L;n++) {
        currDigitArr = processEachDigit(L, mainArr, currDigitArr);
    }
return mainArr;
}

      

now you can call getPermutationArray(<any number>)

with any number and this will return an array for you, now try to map it to that array. if you fail i will help you, it is an easy job.

Note: I could write a small segment of code, but just wrote so many things to explain it correctly and there can be so many approaches as well, just tried one of them, I want to go for recursion using recursion, we can achieve this as well ... comment if something is unclear.

Happy coding :)

+1


source







All Articles