Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Разбить массив на подмассивы (https://javascript.ru/forum/misc/83628-razbit-massiv-na-podmassivy.html)

DzonyB 28.01.2022 17:10

Разбить массив на подмассивы
 
Добрый день , прошу помощи . Как составить цикл, чтобы разбить массив на подмассивы .
Дано arr= [1,2,4,7,1,6,2,8]
Нужно получить arr_new=[[8,2],[6,4],[1,2,7,1]]
T.e разбить массив , на подмассивы , чтобы сумма в подмассивах как можно ближе была равна 10 .
Если нужны мои потуги кода , я могу выложить , но пока своим умом дойти не могу.
Заранее, спасибо. :(

рони 28.01.2022 17:39

DzonyB,
для медитации ... решения не 100%
https://javascript.ru/forum/misc/797...e-massiva.html

надо искать тем с десяток наберётся.

DzonyB 28.01.2022 23:45

Цитата:

Сообщение от рони (Сообщение 543340)
DzonyB,
для медитации ... решения не 100%
https://javascript.ru/forum/misc/797...e-massiva.html

надо искать тем с десяток наберётся.

Спасибо за ссылку , буду искать.:thanks:

рони 29.01.2022 00:07

Цитата:

Сообщение от DzonyB
Если нужны мои потуги

аналогично :lol: что - то из разряда ... слеплено из ... )))

<script>
        function permute(arr) {
            let l = arr.length,
                used = Array(l),
                data = Array(l);
            return function* backtracking(pos) {
                if (pos == l) yield data.slice();
                else
                    for (let i = 0; i < l; ++i)
                        if (!used[i]) {
                            used[i] = true;
                            data[pos] = arr[i];
                            yield* backtracking(pos + 1);
                            used[i] = false;
                        }
            }(0);
        }
        function sumArray(arr) {
            return arr.reduce((a, b) => a + b, 0)
        }
        function permutDevide(arr, n) {
            arr.sort((a, b) => a - b);
            const gen = permute(arr);
            let current = gen.next();
            let max = [],
                k = 0,
                sum = sumArray(arr);
            while (!current.done) {
                let temp = [],
                    num = 0,
                    d = 0,
                    s = sum;
                const res = [temp];
                for (const elem of current.value) {
                if(num + elem > n && s != elem || (elem > n)) {
                if(num == n) d++;
                temp = [elem];
                res.push(temp);
                num = elem;
                }
                else {
                 temp.push(elem);
                 num += elem;
                }

                s -= elem;
                }
                if(num == n) d++;
                if (!temp.length) res.pop();
                if (d >= sum / n - 1.5) return res;
                if (!max.length) max = res;
                if (d > k) {
                    max = res;
                    k = d
                };
                current = gen.next();
            }
            return max
        }
        const test = [
            [1, 2, 4, 7, 1, 6, 2, 8], [5, 2, 5, 1, 5, 4, 6, 3], [100, 8, 7, 3, 1, 45, 20, 6, 4], [2, 2, 3, 9, 5, 6, 1], [3, 3, 3, 3, 3, 3], [3, 7, 3, 3, 3, 3]
        ];
        for (const arr of test) document.write(`${JSON.stringify(arr)} => ${JSON.stringify(permutDevide(arr, 10))}<br>`)
    </script>

DzonyB 29.01.2022 01:16

Еще раз спасибо , когда копирую Ваш код к себе в браузер , выдает кучу ошибок . Буду пробовать сам .

DzonyB 29.01.2022 15:09

Ничего не получается , мож поможете составить цикл , только по одному моему массиву , а не по группе , как в предложенном ранее варианте.
Заранее спасибо.

P.S хоть и не получается , но плюсы небольшие есть. Перелопатил всю книгу. :)))

рони 29.01.2022 15:13

Цитата:

Сообщение от DzonyB
мож поможете составить цикл , только по одному моему массиву ,

:-? :-? :-?
permutDevide([1,2,4,7,1,6,2,8], 10);

DzonyB 29.01.2022 15:35

Цитата:

Сообщение от рони (Сообщение 543374)
:-? :-? :-?
permutDevide([1,2,4,7,1,6,2,8], 10);

Или я дурак , или лыжи не едут .
Мне не нужна Ваша функция
function permut(arr){
}

Я вчера писал , что при копировании этой функции в PHP Storm и браузере ругается на строку
if (pos == l) yield data.slice();
. а без этой функции вторая не работает . Пробовал переделать но пока не получилось . Пробую сам , тоже пока результат 0 .
И я не очень понял эту часть кода
while (!current.done)

Поэтому и попросил помощи . Вы в своем коде разберетесь быстрее чем , но если нет , так нет . Все равно спасибо.

DzonyB 29.01.2022 15:40

P.S Я работаю в HTML и использую Vue . Может в этом проблема ?

рони 29.01.2022 16:15

DzonyB,
не понимаю.

DzonyB 29.01.2022 16:25

Цитата:

Сообщение от рони (Сообщение 543380)
DzonyB,
не понимаю.

Очень жаль , что мы друг друга не понимаем , или не хотим понять . Попробую обьяснить еще раз помогите составить цикл.
Имеется исходный массив и то что я должен получить. Только без дополнительных функций по разбиеню массивов.

DzonyB 29.01.2022 16:31

Цитата:

Сообщение от рони
DzonyB,
не понимаю.

очень жаль , что мы не понимаем друг друга.

DzonyB 29.01.2022 16:35

Попробую обьяснить еще раз , Вы можете помогти ставить цикл , без Вашей первой функции permute() ??? она мне не нужна , да и работает с ошибкой ругается на строку.
for (let i = 0; i &lt; l; ++i)

Ошибка
Uncaught SyntaxError: Unexpected token ';'

рони 29.01.2022 17:00

DzonyB,
строки 17 - 26 по ссылке
http://javascript.ru/forum/css-html/...tml#post524826

и так для развития
http://javascript.ru/forum/misc/7575...-v-vremya.html

DzonyB 29.01.2022 17:17

Цитата:

Сообщение от рони (Сообщение 543384)
DzonyB,
строки 17 - 26 по ссылке
http://javascript.ru/forum/css-html/...tml#post524826

и так для развития
http://javascript.ru/forum/misc/7575...-v-vremya.html

?????????? Эти ссылки имеют какое нибудь отношение к моему вопросу? Или это так , лишь бы отмазаться ? :cray:

рони 29.01.2022 17:45

Цитата:

Сообщение от DzonyB
Эти ссылки имеют какое нибудь отношение к моему вопросу?

видимо я точно не телепат, что вам нужно мне неизвестно)))

DzonyB 29.01.2022 17:54

Цитата:

Сообщение от рони (Сообщение 543380)
DzonyB,
не понимаю.

Цитата:

Сообщение от рони (Сообщение 543388)
видимо я точно не телепат, что вам нужно мне неизвестно)))

Видимо Вы просто не желаете помочь . В самом первом Вашем ответе была доля истины . Но там была ссылка с ответом на другой вопрос, в котором была ненужная мне функция. Я попросил упростить , Вы начали кидаться ссылками . Если нет желания , могли бы просто послать меня и все.
Ну да ладно , помогать , или нет , это Ваше личное желание , и я не могу на это повлиять.
Все равно спасибо Вам , что откликнулись . Хорошего дня.

рони 29.01.2022 17:59

DzonyB,
ты бы для начала толком объяснил что тебе надо, а не в ... лез.

DzonyB 29.01.2022 18:22

Цитата:

Сообщение от рони (Сообщение 543390)
DzonyB,
ты бы для начала толком объяснил что тебе надо, а не в ... лез.

Да я никуда и не лезу . ОК! Попытаюсь обьяснить сначала.
Дано arr= [1,2,4,7,1,6,2,8]
Нужно получить arr_new=[[8,2],[6,4],[1,2,7,1]]
Т.е -"Разделите элементы массива на группы, сумма каждой из которых максимально равна друг другу."
Вариантов решения здесь несколько , можно разбить
1. array1=>[ [8][6,2][7,1][1,2,4] ]=> 8 - 4группы 
2. array2=>[[8,2][7,2,1][6,4,1]]=>10/11 - 3 группы
3. array3=>[[1,2,4,7,1][6,2,8]]=>15/16 -2 группы

Я выбрал среднюю группу , чтобы упростить задачу . Т.е создать функцию в которую передается 2 аргумента , массив и кол. групп . И на выходе получаем один из трех массивов в зависимости от количества групп .
В первом Вашем ответе была ссылка , в принципе по той ссылке function permutDevide(arr) делает то , что нужно , но в ней вызывается функция function permute(arr) . А вот с ней и проблема код не работает , выдает ошибки , я писал . А Вы мне начинаете давать другие ссылки. Если честно , я уже запутался, мозг кипит.
Надеюсь я понятно изложил.

рони 29.01.2022 19:29

Цитата:

Сообщение от DzonyB
Т.е создать функцию в которую передается 2 аргумента , массив и кол. групп . И на выходе получаем один из трех массивов в зависимости от количества групп .

не знаю.

DzonyB 29.01.2022 19:42

Цитата:

Сообщение от рони (Сообщение 543392)
не знаю.

Понял, тема закрыта. Спасибо, Вы очень любезны. :thanks:

DzonyB 31.01.2022 20:09

Цитата:

Сообщение от рони (Сообщение 543392)
не знаю.

Рони,Выкладываю свои потуги. В глубине души понимаю , что кривовато , но лучше сделать ума , не хватило .
Недостатки ,
1. При указании суммы подгруппы не elem_sum+1 , т.е ne 11 , a 10 , разбивает только на подгруппы с суммой 10 , а в основном массиве остается 1 .
2. Остается пустой массив.
Если не трудно , прошу покритиковать , а еще лучше подправить . Я с удовольствием поизучаю рабочий вариант.

<script>

    const webstore = new Vue({
        el: '#app',
        data() {
            return {

                array_in: [1, 2, 4, 7, 1, 6, 2, 8],

                array_original: [],

                count_group: 3,

                array_out: [],

            }
        },

        created() {

            this.getArray(this.array_in, this.count_group);
        },

        methods: {

            getArray(arr, n) {

                let arr_out = [];
                n = this.count_group;
                let arr_clone = [arr_out];
                let arr_length = arr.length;

                this.array_original = Array.from(this.array_in);

                arr.sort((a, b) => b - a);

               let elem_sum = parseInt(arr.reduce((x, y) => x + y) / n);

                for (let i = 0; i <= n - 1; i++) {

                    for (let i = 0; i <= arr_length - 1; i++) {

                        if (arr_out.reduce((x, y) => x + y, 0) + arr[i] <= elem_sum + 1) {
                            arr_out.splice(0, 0, arr[i]);
                            delete arr[i];
                        }
                    }

                    if (arr_out.reduce((x, y) => x + y, 0) <= elem_sum + 1) {
                        arr_out = [] , arr_clone.push(arr_out);
                    }
                }
                this.array_out = arr_clone;

            }// End Get array
        },

    }); //End Vue

</script>

рони 01.02.2022 00:05

vue разбить массив на n частей
 
DzonyB,

<!DOCTYPE html>
<html>
<head>
    <title>Untitled</title>
    <meta charset="utf-8">
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <ul>
            <li v-for="el of array_out">
                {{el}}
            </li>
        </ul>
    </div>
    <script>
        const webstore = new Vue({
            el: '#app',
            data() {
                return {
                    array_in: [1, 2, 4, 7, 1, 6, 2, 8],
                    count_group: 3,
                    array_out: []
                }
            },
            created() {
               this.array_out = this.getArray(this.array_in, this.count_group);
            },
            methods: {
                getArray(arr, size) {
                    arr = arr.slice().sort((a, b) => b - a);
                    let arr_current = [];
                    let arr_calculated = [arr_current];
                    let average = (arr, size) => Math.trunc(arr.reduce((x, y) => x + y) / size);
                    for (let i = 0; size; i++) {
                        let limit = average(arr, size--);
                        for (let k = 0; k < arr.length;) {
                            if (limit - arr[k] >= 0) {
                                limit -= arr[k];
                                arr_current.push(arr[k]);
                                arr.splice(k, 1);
                            } else k++;
                        }
                        if(size == 1){
                        arr_calculated.push(arr);
                        break;
                        }
                        if (arr.length) {
                        arr_current = [];
                        arr_calculated.push(arr_current);
                        }
                    }
                    return arr_calculated;
                } // End Get array
            },
        }); //End Vue
    </script>
</body>
</html>

DzonyB 01.02.2022 08:23

Рони, Спасибо дружище. Наконец то мы поняли друг друга .:)
С удовольствием буду анализировать ошибки в своем говнокоде, ;)
Еще раз спасибо.

рони 01.02.2022 09:15

DzonyB,
#23 добавил немного "косметики" :)

DzonyB 01.02.2022 16:01

Цитата:

Сообщение от рони (Сообщение 543423)
DzonyB,
#23 добавил немного "косметики" :)

Спасибо еще раз. :thanks:


Часовой пояс GMT +3, время: 16:14.