【问题标题】:Merging multiple sorted ranges合并多个排序范围
【发布时间】:2015-01-23 18:42:57
【问题描述】:

我正在尝试使用 std::merge 反复合并多个范围。它说模板参数推导失败。有人可以解释为什么这不会编译吗?是使用多包的问题吗?

#include <algorithm>
#include <vector>

template <typename OutputIterator>
OutputIterator multi_merge (OutputIterator result) {return result;}

template <typename InputIterator1, typename InputIterator2, typename OutputIterator,
    typename... InputIterators1, typename... InputIterators2>
OutputIterator multi_merge (InputIterator1 first1, InputIterators1... firsts1, 
InputIterator1 last1, InputIterators1... lasts1,
InputIterator2 first2, InputIterators2... firsts2, InputIterator2 last2, 
InputIterators2... lasts2, OutputIterator result) {
    // incorrect algorithm deleted
    return multi_merge (firsts1..., lasts1..., firsts2..., lasts2..., result);
}

int main() {
    std::vector<int> a = {3,4,6,1,2},  b = {6,8,9,2},  c = {6,7,4,5,2}, result;
    std::sort (a.begin(), a.end());
    std::sort (b.begin(), b.end());
    std::sort (c.begin(), c.end());
    multi_merge (a.begin(), b.begin(), c.begin(), a.end(), b.end(), c.end(),
        std::back_inserter(result));
}

另外,我希望参数的顺序是 first1、last1、first2、last2、...,但这是小事。

编辑:我意识到我的合并逻辑是错误的。我认为是这样的:首先将 [a1, b1) 与 [a2, b2) 合并,然后使用生成的合并范围 [merged1,merged2) 并与 [a3, b3) 合并,依此类推。所以编译错误不再是问题。另一个想法是将每个范围内的所有元素复制到一个容器中,然后对其进行排序(如果这有任何意义的话),但这不是我寻求的解决方案,但如果这是唯一的方法,我会接受它。

【问题讨论】:

  • 当您遇到编译器错误时,请将其包含在问题中。最好使用复制/粘贴。
  • 可变参数模板参数应该是最后一个。您可以将它们与std::tuple 分组。
  • 它说模板参数推导失败,但上面是一个完整的例子,任何人都可以使用。
  • @Jarod42。论点中没有元组就不能有解决方案吗?理想情况下,multi_merge 应该与 std::merge 完全一样使用,但具有多个范围的扩展参数,对吧?
  • @prestokeys:您也可以将签名更改为template &lt;typename OutputIterator, typename ... InputIterators&gt; OutputIterator multi_merge(OutputIterator, InputIterators...);

标签: c++ sorting merge


【解决方案1】:

问题是每个模板中不能有多个可变参数。

你怎么知道一个从哪里开始,另一个在哪里结束?

【讨论】:

    【解决方案2】:

    好的,我更改了开头帖子中的函数签名。现在它正在工作。

    #include <iostream>
    #include <vector>
    #include <array>
    #include <algorithm>
    
    template <typename Container>
    std::vector<typename Container::value_type> multi_merge (const Container& container) {
        return container;
    }
    
    template <typename Container1, typename Container2, typename... Containers>
    std::vector<typename Container1::value_type> multi_merge (const Container1& container1,
    const Container2& container2, const Containers&... containers) {
        std::vector<typename Container1::value_type> v;
        auto it = std::merge (container1.begin(), container1.end(), container2.begin(), 
            container2.end(), std::back_inserter(v));
        return multi_merge (v, containers...);
    }
    
    int main() {
        std::vector<int> a = {3,4,6,1,2},  b = {6,8,9,2}, c = {6,7,4,5,2}, d = {3,2,4};
        std::array<int,6> e = {5,6,2,7,1,3};
        std::sort (a.begin(), a.end());
        std::sort (b.begin(), b.end());
        std::sort (c.begin(), c.end());
        std::sort (d.begin(), d.end());
        std::sort (e.begin(), e.end());
        const std::vector<int> result = multi_merge (a, b, c, d, e);
        for (int x : result) std::cout << x << ' '; // 1 1 2 2 2 2 2 3 3 3 4 4 4 5 5 6 6 6 6 7 7 8 9
    }
    

    我仍然想知道如何使用我开篇文章中的原始签名来完成它,因为该签名遵循 std::merge 的精神(仅使用迭代器),并使用输出迭代器概括输出容器。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-04-18
      • 1970-01-01
      • 2021-02-24
      • 2016-04-13
      • 2021-07-22
      • 1970-01-01
      • 2019-03-21
      • 1970-01-01
      相关资源
      最近更新 更多