我正在寻找一种解决方案,将不同大小的项目列表拆分成N个大小相似的组,同时保持项目顺序.

这是一个约翰逊算法或宾格包装.我仍然不知道如何为N组实现它,并保持项目顺序.

分成3组的示例:

要分发的项目:

  • 项目A-尺码5
  • 物品B-尺码1
  • 物品C-尺码8
  • 物品D-尺码2
  • 项目E-尺寸3

请注意,情况并非如此.

Group 1 (total size 6): Item A, Item B
Group 2 (total size 8): Item C
Group 3 (total size 5): Item D, Item E

function distributeItems(items, numGroups) {
    const totalItems = items.length;
    const groupSizes = Array.from({ length: numGroups }, () => 0);
    const groups = Array.from({ length: numGroups }, () => []);

    for (let i = 0; i < totalItems; i++) {
        const currentItem = items[i];
        let minSizeIndex = 0;

        for (let j = 1; j < numGroups; j++) {
            if (groupSizes[j] < groupSizes[minSizeIndex]) {
                minSizeIndex = j;
            }
        }

        groups[minSizeIndex].push(currentItem);
        groupSizes[minSizeIndex] += currentItem.size;
    }

    for (let i = 0; i < numGroups; i++) {
        console.log(`Group ${i + 1} (total size ${groupSizes[i]}): ${groups[i].map(item => item.title).join(', ')}`);
    }
}

const items = [
    { title: 'Item A', size: 5 },
    { title: 'Item B', size: 1 },
    { title: 'Item C', size: 8 },
    { title: 'Item D', size: 2 },
    { title: 'Item E', size: 3 },
];

distributeItems(items, 3);

推荐答案

算法如下:

  1. 计算所有项目的总大小
  2. 获取组的大小
  3. 根据当前项目大小的总和迭代项目并推送到组

这不包括两组人共享等量物品的情况.

const items = [
{ title: 'Item A', size: 5 },
{ title: 'Item B', size: 1 },
{ title: 'Item C', size: 8 },
{ title: 'Item D', size: 2 },
{ title: 'Item E', size: 3 },
];

console.log(distributeItems(items, 3));

function distributeItems(items, groupNum) {
const total = items.reduce((r, item) => r + item.size, 0);
const chunkTotal = total/groupNum|0;
const groups = Array.from({length: groupNum}, () => []);
let sum = 0, groupIdx = 0;
for(const item of items){
    const group = groups[groupIdx];
    sum += item.size;
    if(sum >= chunkTotal){
        const right = chunkTotal - (sum - item.size);
        const left = sum = Math.min(chunkTotal, item.size - right);
        groupIdx++;
        if(right < left){
            groups[groupIdx].push(item);
            continue;   
        }
    }
    group.push(item);
    
}

return groups;
}

Javascript相关问答推荐

我可以使用CSS有效地实现最大宽度=100%和最大高度=100%,而无需父母有明确的/固定的宽度和高度,替代方法吗?

扫描qr code后出错whatter—web.js

InDesign—创建一个独立的窗口,在文档中进行更正时保持打开状态

如何在mongoose中链接两个模型?

构造HTML表单以使用表单数据创建对象数组

我在我的Java代码中遇到了问题,代码的一部分看不到先前定义的对象

当Redux提供程序访问Reduxstore 时,可以安全地从Redux提供程序外部调用钩子?

无法读取未定义错误的属性路径名''

Prisma具有至少一个值的多对多关系

如何从HTML对话框中检索单选项组的值?

钛中的onClick事件需要在两次点击之间等待几秒钟

react -原生向量-图标笔划宽度

如何修复使用axios运行TSC index.ts时出现的错误?

Clip-Path在网页浏览器(Mozilla、Edge、Chrome)上不能正常工作,但在预览版Visual Code Studio HTML、CSS、JS上却能很好地工作

React Refs不与高阶组件(HOC)中的动态生成组件一起工作

JavaScript -复制到剪贴板在Windows计算机上无效

为什么我的SoupRequest";被重置为初始值,以及如何修复它?

需要刷新以查看Mern堆栈应用程序中的更改

错误400:当我试图在React中使用put方法时,该字段是必需的

使用JAVASCRIPT-使用If和Else If多次判断条件-使用JAVASRIPT对象及其属性