Какое математическое обоснование методов, используемых в этой функции, дает желаемые результаты? - PullRequest
1 голос
/ 23 мая 2019

У меня есть функция, которая генерирует все комбинации заданной строки;не включая перестановки.Я считаю, что я полностью понимаю логику того, как данная строка передается через функцию, дающую желаемые результаты.Что я хочу понять, так это математическое обоснование основных методов, с помощью которых функция обрабатывает элементы строки в массиве, который включает все возможные комбинации.

Вот код с сильными комментариями, который отображает мое текущее пониманиелогической обработки функции.

function generateAllCombinationsOfString (str1) { //let str1 = "dog"
    // convert str1 into an array
    var array1 = []; // create var in order to capture elements of str1 into an array
        for (var x = 0, y = 1; x < str1.length; x++,y++) {
            array1[x] = str1.substring(x, y); // we will add each character to array1, in order, starting with the first then ending the loop once the last character has been included in array1
            // for each iteration: x = 0, y = 1     x < str1.length     x++, y++        array1[x] = str1.substring(x, y)
            // iteration 1:      x = 0, y = 1         yes                1    2         array1[0] = str1.substring(0, 1) = "d"
            // iteration 2:      x = 1, y = 2       yes                2    3         array1[1] = str1.substring(1, 2) = "o"
            // iteration 3:      x = 2, y = 3       yes                3    4         array1[2] = str1.substring(2, 3) = "g"
            // iteration 4:      x = 3, y = 4       no
            // end of loop
        }
    // create array containing all combinations of str1
    var combi = []; // create var to capture each possible combination within an array
    var temp = "";  // create cache to temporarily hold elements each possible combination before adding to an array
    var slent = Math.pow(2, array1.length);
        for (var i = 0; i < slent; i++){
            temp = "";
            // for each iteration:      i = 0       i < slent       i++     var combi = []; temp = ""; var slent = Math.pow(2, array1.length)
            // iteration 1:             i = 0         yes            1      var combi = []; temp = ""; var slent = Math.pow(2, 3) = 8
            // iteration 2:             i = 1         yes            2      var combi = [d]; temp = ""; var slent = Math.pow(2, 3) = 8
            // iteration 3:             i = 2         yes            3      var combi = [d, o]; temp = ""; var slent = Math.pow(2, 3) = 8
            // iteration 4:             i = 3         yes            4      var combi = [d, o, do]; temp = ""; var slent = Math.pow(2, 3) = 8
            // iteration 5:             i = 4         yes            5      var combi = [d, o, do, g]; temp = ""; var slent = Math.pow(2, 3) = 8
            // iteration 6:             i = 5         yes            6      var combi = [d, o, do, g, dg]; temp = ""; var slent = Math.pow(2, 3) = 8
            // iteration 7:             i = 6         yes            7      var combi = [d, o, do, g, dg, og]; temp = ""; var slent = Math.pow(2, 3) = 8
            // iteration 8:             i = 7         yes            8      var combi = [d, o, do, g, dg, og, dog]; temp = ""; var slent = Math.pow(2, 3) = 8
            // iteration 9:             i = 8         no
            // end of loop
            for (var j = 0; j < array1.length; j++) {
                if ((i & Math.pow(2, j))) {
                    temp += array1[j];
                    // for each iteration:      j = 0       j < array1.length       j++     if((i & Math.pow(2, j)))?                             {temp += array1[j]}
                    // iteration 1-1:           j = 0         yes                    1      if((0 & Math.pow(2, 0)))? => if((0 & 1))? // false
                    // iteration 1-2:           j = 1         yes                    2      if((0 & Math.pow(2, 1)))? => if((0 & 2))? // false
                    // iteration 1-3:           j = 2         yes                    3      if((0 & Math.pow(2, 2)))? => if((0 & 4))? // false
                    // iteration 1-4:           j = 3         no
                    // end of loop
                    // iteration 2-1:           j = 0         yes                    1      if((1 & Math.pow(2, 0)))? => if((1 & 1))? // true  // {temp += array1[0]} => temp = "d"}
                    // iteration 2-2:           j = 1         yes                    2      if((1 & Math.pow(2, 1)))? => if((1 & 2))? // false
                    // iteration 2-3:           j = 2         yes                    3      if((1 & Math.pow(2, 2)))? => if((1 & 4))? // false
                    // iteration 2-4:           j = 3         no
                    // end of loop
                    // iteration 3-1:           j = 0         yes                    1      if((2 & Math.pow(2, 0)))? => if((2 & 1))? // false
                    // iteration 3-2:           j = 1         yes                    2      if((2 & Math.pow(2, 1)))? => if((2 & 2))? // true  // {temp += array1[1] => temp = "o"}
                    // iteration 3-3:           j = 2         yes                    3      if((2 & Math.pow(2, 2)))? => if((2 & 4))? // false
                    // iteration 3-4:           j = 3         no
                    // end of loop
                    // iteration 4-1:           j = 0         yes                    1      if((3 & Math.pow(2, 0)))? => if((3 & 1))? // true  // {temp += array1[0] => temp = "d"}
                    // iteration 4-2:           j = 1         yes                    2      if((3 & Math.pow(2, 1)))? => if((3 & 2))? // true  // {temp += array1[1] => temp = "do"}
                    // iteration 4-3:           j = 2         yes                    3      if((3 & Math.pow(2, 2)))? => if((3 & 4))? // false //
                    // iteration 4-4:           j = 3         no
                    // end of loop
                    // iteration 5-1:           j = 0         yes                    1      if((4 & Math.pow(2, 0)))? => if((4 & 1))? // false //
                    // iteration 5-2:           j = 1         yes                    2      if((4 & Math.pow(2, 1)))? => if((4 & 2))? // false //
                    // iteration 5-3:           j = 2         yes                    3      if((4 & Math.pow(2, 2)))? => if((4 & 4))? // true  // {temp += array1[2] => temp = "g"}
                    // iteration 5-4:           j = 3         no
                    // end of loop
                    // iteration 6-1:           j = 0         yes                    1      if((5 & Math.pow(2, 0)))? => if((5 & 1))? // true  // {temp += array1[0] => temp = "d"}
                    // iteration 6-2:           j = 1         yes                    2      if((5 & Math.pow(2, 1)))? => if((5 & 2))? // false //
                    // iteration 6-3:           j = 2         yes                    3      if((5 & Math.pow(2, 2)))? => if((5 & 4))? // true  // {temp += array1[2] => temp = "dg"}
                    // iteration 6-4:           j = 3         no
                    // end of loop
                    // iteration 7-1:           j = 0         yes                    1      if((6 & Math.pow(2, 0)))? => if((6 & 1))? // false // 
                    // iteration 7-2:           j = 1         yes                    2      if((6 & Math.pow(2, 1)))? => if((6 & 2))? // true  // {temp += array1[1] => temp = "o"}
                    // iteration 7-3:           j = 2         yes                    3      if((6 & Math.pow(2, 2)))? => if((6 & 4))? // true  // {temp += array1[2] => temp = "og"}
                    // iteration 7-4:           j = 3         no         
                    // end of loop
                    // iteration 8-1:           j = 0         yes                    1      if((7 & Math.pow(2, 0)))? => if((7 & 1))? // true  // temp += array1[0] => temp = "d"}
                    // iteration 8-2:           j = 1         yes                    2      if((7 & Math.pow(2, 1)))? => if((7 & 2))? // true  // temp += array1[1] => temp = "do"}
                    // iteration 8-3:           j = 2         yes                    3      if((7 & Math.pow(2, 2)))? => if((7 & 4))? // true  // temp += array1[2] => temp = "dog"}
                    // iteration 8-4:           j = 3         no 
                    // end of loop
                }
            }
            if (temp !== "") { // if var temp is not an empty string then we add elements of var temp to end of the array var combi at the end of each loop cycle
                combi.push(temp); 
                // for each iteration       if(temp !== "")?
                // iteration 1:             if(temp !== "")? // false //
                // iteration 2:             if(temp !== "")? // true // combi.push(temp) => combi.push("d") 
                // iteration 3:             if(temp !== "")? // true // combi.push(temp) => combi.push("o") 
                // iteration 4:             if(temp !== "")? // true // combi.push(temp) => combi.push("do")
                // iteration 5:             if(temp !== "")? // true // combi.push(temp) => combi.push("g")
                // iteration 6:             if(temp !== "")? // true // combi.push(temp) => combi.push("dg")
                // iteration 7:             if(temp !== "")? // true // combi.push(temp) => combi.push("og")
                // iteration 8:             if(temp !== "")? // true // combi.push(temp) => combi.push("dog")
            }
        }
        // join array of combinations while seperating each by a new line
        console.log(combi.join("\n"))
        /*  expected output if str1 = "dog"

            d
            o
            do
            g
            dg
            og
            dog

        */
}

Ниже приведен раздел, который включает в себя фрагменты, которые я хотел бы, чтобы понять причины этого.

    var combi = [];
    var temp = "";  
    var slent = Math.pow(2, array1.length);
        for (var i = 0; i < slent; i++){
            temp = "";

            for (var j = 0; j < array1.length; j++) {
                if ((i & Math.pow(2, j))) {
                    temp += array1[j];
                }
            }
            if (temp !== "") { 
                combi.push(temp); 
            }
        }

Как получается, чтопеременная «slent» с приведенным выше определением дает нам точное условие, при котором весь цикл останавливается в нужный момент после добавления последних возможных комбинаций в var combi?

, более того, второй цикл FOR в этомраздел также содержит аналогичное условие, которое работает вместе с начальным выражением j = 0, а также условие, содержащееся в операторе IF, которое, кажется, прекрасно обрабатывает и помещает каждую возможную комбинацию в переменную "combi", сохраняя при этом frдобавление неверных элементов в каждую итерацию.Как получилось, что методы Math.pow (), используемые в этой функции, дают желаемые результаты?

Каковы причины вышеупомянутых ключевых моментов?Я чувствую, что полностью понимаю, «как» работает функция, но мне хотелось бы знать, «почему» работает метод.Как узнать, что эти методы вместе позволят функции вернуть желаемое?

Я чувствую, что это имеет отношение к математическому определению комбинаций, но я не знаком с этой конкретной темой, поэтому яинтересно, может ли кто-нибудь просветить меня, если я структурировал этот вопрос так, чтобы это имело смысл?

1 Ответ

1 голос
/ 23 мая 2019

В общем, с n различными символами, взятыми по порядку, с некоторыми взятыми или нет, существует 2 ^ n возможностей наборов символов (включая пустой набор, который подпрограмма старается не добавлять). Они связаны с возможными n-значными числами основания 2, которые варьируются от 0 до 2 ^ n-1. Перебирая эти числа, для каждого номера код проверяет бит, связанный с каждым символом, и включает в себя символ, если бит равен 1, и не равен, если он равен 0.

...