如何有效地按组对列表进行排序?

时间:2019-01-24 22:15:36

标签: java algorithm performance sorting grouping

我需要通过给定的元素“块”或“组”对给定的排序列表进行分组。例如:

提供列表:

[A, B, C, D, E, F, G, H, I, J]

和组

[A, C, D]
[F, E]
[J, H, I]

结果应该是

[A, C, D, B, F, E, G, J, H, I]

元素块不能与非组元素混合。块应具有相同的顺序。列表中的其他元素应保持其顺序。


我已经找到了解决方案。但这不是您将看到的最有效的代码。

我也在使用Java 6 ...

public static List<CategoryProduct> sortProductsByBlocks(List<CategoryProduct> products, CategoryBlocks categoryBlocks) {
    if (!validateCategoryBlocks(categoryBlocks)) {
        return products;
    }
    Map<String, BlockView> mapProductByBlock = mapBlocksByPartnumber(categoryBlocks);
    Map<String, BlockView> mapFirstProductByBlock = mapFirstProductByBlock(categoryBlocks);
    Map<Integer, Block> blocksById = blocksById(categoryBlocks);
    List<CategoryProduct> sortedProduct = Lists.newArrayList();
    Map<String, CategoryProduct> productsMapByPartNumber = ProductHelper.getProductsMapByPartNumber(products);
    List<CategoryProduct> processedProducts = Lists.newArrayList();
    int j = 0;
    for (int i = 0; i < products.size(); i++) {
        CategoryProduct product = products.get(i);
        if (blocksById.isEmpty() && !processedProducts.contains(product)) {
            sortedProduct.add(j++, product);
            processedProducts.add(product);
        }
        if (!processedProducts.contains(product) && (mapFirstProductByBlock.get(product.getPartNumber()) != null
                || mapProductByBlock.get(product.getPartNumber()) == null)) {
            BlockView blockView = mapProductByBlock.get(product.getPartNumber());
            if (blockView != null) {
                Block block = blocksById.get(blockView.getBlockId());
                if (block == null) {
                    sortedProduct.add(j++, product);
                    continue;
                }
                for (BlockProduct blockProduct : block.getProducts()) {
                    CategoryProduct categoryProduct = productsMapByPartNumber.get(blockProduct.getPartnumber());
                    sortedProduct.add(j++, categoryProduct);
                    processedProducts.add(categoryProduct);
                }
                blocksById.remove(blockView.getBlockId());
            } else {
                sortedProduct.add(j++, product);
                processedProducts.add(product);
            }
        }
    }

    return sortedProduct;
}

欢迎提出任何改进和加快速度的建议。

(使用改进的代码进行编辑)

public static List<CategoryProduct> sortProductsByBlocks2(List<CategoryProduct> products,
        CategoryBlocks categoryBlocks) {
    if (!validateCategoryBlocks(categoryBlocks)) {
        return products;
    }

    Map<String, Integer> blocksIdByFirstPartnumber = Maps.newHashMap();
    List<String> partnumbersInBlocks = Lists.newArrayList();
    for (int k = 0; k < categoryBlocks.getBlocks().size(); k++) {
        Block block = categoryBlocks.getBlocks().get(k);
        if (block != null && block.getProducts() != null) {
            for (int i = 0; i < block.getProducts().size(); i++) {
                BlockProduct blockProduct = block.getProducts().get(i);
                if (i == 0) {
                    blocksIdByFirstPartnumber.put(blockProduct.getPartnumber(), k);
                } else {
                    partnumbersInBlocks.add(blockProduct.getPartnumber());
                }
            }
        }
    }

    CategoryProduct[] result = new CategoryProduct[products.size()];
    Map<String, Integer> productsIndex = Maps.newHashMap();
    Map<String, CategoryProduct> categoryProductByPartnumber = Maps.newHashMap();
    int indexResult = 0;
    for (CategoryProduct categoryProduct : products) {
        String partNumber = categoryProduct.getPartNumber();
        if (!partnumbersInBlocks.contains(partNumber)) {
            if (blocksIdByFirstPartnumber.get(partNumber) != null) {
                Block categoryProductBlock = categoryBlocks.getBlocks()
                        .get(blocksIdByFirstPartnumber.get(partNumber));
                result[indexResult] = categoryProduct;
                indexResult++;
                for (int i = 1; i < categoryProductBlock.getProducts().size(); i++) {
                    BlockProduct blockProduct = categoryProductBlock.getProducts().get(i);
                    if (categoryProductByPartnumber.get(blockProduct.getPartnumber()) != null) {
                        result[indexResult] = categoryProductByPartnumber.get(blockProduct.getPartnumber());
                    } else {
                        productsIndex.put(blockProduct.getPartnumber(), indexResult);
                        result[indexResult] = null;
                    }
                    indexResult++;
                }
            } else {
                result[indexResult] = categoryProduct;
                indexResult++;
            }
        } else {
            if (productsIndex.get(partNumber) != null) {
                result[productsIndex.get(partNumber)] = categoryProduct;
            } else {
                categoryProductByPartnumber.put(partNumber, categoryProduct);
            }
        }
    }
    return Lists.newArrayList(Arrays.asList(result));
}

性能:

元素新算法旧算法

1200 0.002s 0.129s

12000 0.021s 14.673s

2 个答案:

答案 0 :(得分:1)

根据您提交的代码,我无法弄清楚您的算法是如何正常工作的。

我可以编写另一种算法来完成任务。

  1. 标记每个组的第一个元素

    <ion-list no-lines>
    <ion-card *ngFor="let thing of cardz; let i = index;">
        <ion-item>
            <ion-avatar item-start>
                <img src="{{thing.ppsrc}}">
            </ion-avatar>
            <h2 (click)="openHome()">{{thing.name}}</h2>
            <p>23 Jan 2019</p>
        </ion-item>
        <img class="big" src={{thing.isrc}}>
      <ion-card-content>
        <h1>{{thing.title}}</h1>  
        <p>{{thing.content}}</p>
      </ion-card-content>
    </ion-card>
    </ion-list>
    
  2. [A,C,D] -> A 删除组中所有未标记的元素

    list(to_be_sorted)
  3. 执行列表排序

    [A,C,D] -> remove [C,D]
    
  4. 根据标记放置已删除的元素

    result ([A,B,F,G,J])
    

时间复杂度与排序算法

答案 1 :(得分:0)

根据您的定义,尚不清楚将给定列表和“组”(数组)中的结果合并的条件是什么。但是,这是根据您的要求使用断言

的解决方案
  

“您希望列表的第一个元素不包含在插入在各组之间的任何组中...”

/content/content-name/content-id

//结果

/content