首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >列表中以最大计数为限的项目的随机分布

列表中以最大计数为限的项目的随机分布
EN

Stack Overflow用户
提问于 2015-02-13 15:28:40
回答 1查看 302关注 0票数 0

我有一个包含x项的项目的List

我想在其他清单中随机分发这些物品,条件如下:

  • 每个列表的最大大小为y项(y= 4)
  • 每一项必须最多使用z次(z= 5)

如果x不能同时被y和z整除,那么包含小于y项的列表就可以了。

我正在寻找这样一个方法的Java实现(从1.6到1.8)。谢谢!

编辑

到目前为止,我尝试过的是:

代码语言:javascript
复制
List<Item> myItems;  // Initialized in an other part
int y, z;            // Initialized in an other part
int x = myItems.size();
List<List<Item>> myList = new ArrayList<List<Item>>();
int a = (int) Math.ceil((double)x/y);

Random random = new Random(new Random().nextInt());

for (int j = 0; j < a; j++) {
    myList.add(j, new ArrayList<Item>());
}

for (int i = 0; i < x; i++) {
    int r = random.nextInt(a);
    while (myList.get(r).size() >= y) {
        r = random.nextInt(a);
    }
    myList.get(r).add(myItems.get(i));
}

// Here myList is populated
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-02-16 10:22:29

下面的代码应该可以工作。我在这里假设列表中的项目总数不应该改变。

代码语言:javascript
复制
public List<List<Item>> distribute(List<Item> list, int y, int z) {
    int x = list.size();
    int nLists = (int) Math.ceil((double)x/y);

    // Create result lists
    List<List<Item>> result = new ArrayList<>();
    for (int j = 0; j < nLists; j++)
        result.add(new ArrayList<Item>());
    List<List<Item>> outputLists = new ArrayList<>(result);

    // Create item count store
    Map<Item, Integer> itemCounts = new HashMap<>();
    for (Item item : list)
        itemCounts.put(item, 0);

    // Populate results
    Random random = new Random();
    for (int i = 0; i < x; i++) {
        // Add a random item (from the remaining eligible items)
        // to a random list (from the remaining eligible lists)
        Item item = list.get(random.nextInt(list.size()));
        List<Item> outputList = outputLists.get(random.nextInt(outputLists.size()));
        outputList.add(item);

        // Manage eligible output lists
        if (outputList.size() >= y)
            outputLists.remove(outputList);

        // Manage eligible items
        int itemCount = itemCounts.get(item).intValue() + 1;
        if (itemCount >= z)
            list.remove(item);
        else
            itemCounts.put(item, itemCount);
    }

    return result;
}

注意:上面的代码会改变原来的列表。如果不想这样做,您应该在开始时创建列表的副本。

通过以下输入:

代码语言:javascript
复制
list = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29]   
y = 4
z = 3

这提供了输出列表,如:

代码语言:javascript
复制
[1,10,17,2]
[2,24,6,26]
[16,23,21]
[8,0,3,13]
[12,11,6,0]
[2,17,14,7]
[0,27,7,12]
[7,19,3]

在运行过程中,项目027达到了z限制,并且不再使用。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28502970

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档