Разбить массив на подмассивы
Добрый день , прошу помощи . Как составить цикл, чтобы разбить массив на подмассивы .
Дано arr= [1,2,4,7,1,6,2,8] Нужно получить arr_new=[[8,2],[6,4],[1,2,7,1]] T.e разбить массив , на подмассивы , чтобы сумма в подмассивах как можно ближе была равна 10 . Если нужны мои потуги кода , я могу выложить , но пока своим умом дойти не могу. Заранее, спасибо. :( |
DzonyB,
для медитации ... решения не 100% https://javascript.ru/forum/misc/797...e-massiva.html надо искать тем с десяток наберётся. |
Цитата:
|
Цитата:
<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>
|
Еще раз спасибо , когда копирую Ваш код к себе в браузер , выдает кучу ошибок . Буду пробовать сам .
|
Ничего не получается , мож поможете составить цикл , только по одному моему массиву , а не по группе , как в предложенном ранее варианте.
Заранее спасибо. P.S хоть и не получается , но плюсы небольшие есть. Перелопатил всю книгу. :))) |
Цитата:
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) Поэтому и попросил помощи . Вы в своем коде разберетесь быстрее чем , но если нет , так нет . Все равно спасибо. |
P.S Я работаю в HTML и использую Vue . Может в этом проблема ?
|
DzonyB,
не понимаю. |
Цитата:
Имеется исходный массив и то что я должен получить. Только без дополнительных функций по разбиеню массивов. |
Цитата:
|
Попробую обьяснить еще раз , Вы можете помогти ставить цикл , без Вашей первой функции permute() ??? она мне не нужна , да и работает с ошибкой ругается на строку.
for (let i = 0; i < l; ++i) Ошибка Uncaught SyntaxError: Unexpected token ';' |
DzonyB,
строки 17 - 26 по ссылке http://javascript.ru/forum/css-html/...tml#post524826 и так для развития http://javascript.ru/forum/misc/7575...-v-vremya.html |
Цитата:
|
Цитата:
|
Цитата:
Цитата:
Ну да ладно , помогать , или нет , это Ваше личное желание , и я не могу на это повлиять. Все равно спасибо Вам , что откликнулись . Хорошего дня. |
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) . А вот с ней и проблема код не работает , выдает ошибки , я писал . А Вы мне начинаете давать другие ссылки. Если честно , я уже запутался, мозг кипит. Надеюсь я понятно изложил. |
Цитата:
|
Цитата:
|
Цитата:
Недостатки , 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>
|
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,
#23 добавил немного "косметики" :) |
Цитата:
|
| Часовой пояс GMT +3, время: 12:13. |