【问题标题】:Create a function out of main that merge two arrays C++从 main 创建一个合并两个数组 C++ 的函数
【发布时间】:2018-07-10 23:53:17
【问题描述】:

在我的主要功能中,我有:

#include <iostream>
using namespace std;

int main() {
int merge(int a[], int b[]);

 int dim1, dim2;


cin >> dim1 >> dim2;
 int arrc[dim1];
 int arrd[dim2];

我用以下内容填充我的数组:

    for(int i = 0; i < dim1; i++){
        cin >> arrc[i];
    }

    for(int i = 0; i < dim2; i++){
        cin >> arrd[i];
    }

超出主函数,然后我有:

int merge(int a[], int b[]){
    int q;
    int arrf[q];
 //Code here
}

如何使我的 int q 成为 dim1 和 dim2 的总和? 我试图将合并函数声明为:

 int merge(int a[something], int b[something2]);

但我有错误...

【问题讨论】:

  • 合并(逻辑上)应该返回什么?
  • C++ 中没有 VLA。您的代码根本错误。
  • 它应该返回一个数组,其元素数是我的两个起始数组的元素数之和
  • 欢迎使用 C++ 及其动态大小数组:std::vector。
  • //Code here ....连同“我遇到错误...”不是一个非常完整的问题...

标签: c++ arrays merge


【解决方案1】:

C 风格的数组不能直接从函数返回,当它们通过值传递给函数时,它们会隐式转换为指针,从而丢失它们的大小信息。

要保留 C 样式数组的大小信息,您可以在模板函数中通过引用来获取它,如下所示:

#include <cstddef>

template<std::size_t N>
int &last_element(int(&a)[N])
{
    return a[N - 1];
}

虽然 C 样式的数组不能直接从函数返回,但标准库中的 std::array 可以。

#include <array>

std::array<int, 3> get_array()
{
    return {};
}

将两者放在一起,你可以做类似的事情

#include <algorithm>
#include <array>
#include <cstddef>

namespace detail {

template<std::size_t N1, std::size_t N2>
inline auto join_(const int a1[], const int a2[]) noexcept
{
    std::array<int, N1 + N2> joined;

    std::copy_n(a1, N1, joined.begin());
    std::copy_n(a2, N2, joined.begin() + N1);

    return joined;
}

}//detail

// std::array overload
template<std::size_t N1, std::size_t N2>
auto join(const std::array<int, N1> &a1, const std::array<int, N2> &a2) noexcept
{
    return detail::join_<N1, N2>(a1.data(), a2.data());
}

// C-style array overload
template<std::size_t N1, std::size_t N2>
auto join(const int(&a1)[N1], const int(&a2)[N2]) noexcept
{
    return detail::join_<N1, N2>(a1, a2);
}

【讨论】:

    【解决方案2】:

    代码

    int arrc[dim1];
    int arrd[dim2];
    

    不是有效的 C++。 C++ 没有可变长度数组,因此要使其工作,dim1 和 dim2 必须是编译时常量。相反,您将不得不使用动态分配的数组,或者更好的是std::vector(它基本上只是动态分配数组的包装器,可以重新分配以允许数组增长):

    std::vector<int> arrc(dim1);
    std::vector<int> arrd(dim2);
    

    同样,您可以将 merge 函数的签名更改为:

    std::vector<int> merge(const std::vector<int>& a, const std::vector<int>& b)
    {
        std::vector<int> ret;
        for (int i : a)
        {
            ret.push_back(i);
        }
        for (int i : b)
        {
            ret.push_back(i);
        }
        return ret;
    }
    

    您实际上并不需要实现自己的merge 函数。 C++ 标准库已经提供了std::merge,你会喜欢这样的:

    std::vector<int> arrc(dim1);
    std::vector<int> arrd(dim2);
    // Fill arrc and arrd somehow
    
    std::vector<int> merged;
    std::merge(arrc.begin(), arrc.end(),
               arrd.begin(), arrd.end(),
               std::back_inserter(merged));
    

    【讨论】:

    • 值得一提的是已经有std::merge()。
    • @TheDude 添加了关于 std::merge 的注释。天哪,我等不及要让这些调用变得不那么冗长了。
    • "... 使这些调用不那么冗长。" 使用 std::begin(arrc) 和 std::end(arrc) 等对 IMO 有所帮助。至少有明确的using 指令。
    • 由于您知道最终向量的大小,因此在向其中填充内容之前执行ret.reserve(a.size() + b.size()); 可能是有意义的。此外,您可以放弃第一个for 循环,只需从a 创建ret,例如std::vector&lt;int&gt; ret{a.begin(), a.end()};。
    猜你喜欢
    • 2021-02-24
    • 2021-10-16
    • 2020-06-22
    • 1970-01-01
    • 2018-01-27
    • 2017-11-14
    • 1970-01-01
    • 2019-05-17
    • 2020-01-17
    相关资源
    最近更新 更多