【问题标题】:How do I add numbers of an array to another array?如何将数组的数字添加到另一个数组?
【发布时间】:2022-01-13 12:35:58
【问题描述】:

我想将数组{1, 2, 3} 的数字添加到数组{7, 4, 6} 中,这样我就可以得到一个数组{8, 6, 9},如下所示:

int main(){
    int arr[] = {1, 2, 3};
    int arr2[] = {7, 4, 6};
    arr += arr2; // invalid operands of types ‘int [3]’ and ‘int*’ to binary ‘operator+’
}

【问题讨论】:

  • 您使用什么语言,C 还是 C++?仅标记您实际使用的语言。
  • C 不提供对整个数组进行操作的运算符。您必须自己编写代码。
  • 使用标准的algorithms library,std::transform(std::cbegin(arr), std::cend(arr), std::cbegin(arr2), std::begin(arr), std::plus<>{});

标签: c++ arrays c++17 add


【解决方案1】:

std::valarray 允许您这样做,只需对您的代码进行一些小改动:

#include <iostream>
#include <valarray>

int main() {
    std::valarray<int> arr{1, 2, 3};
    std::valarray<int> arr2{7, 4, 6};
    arr += arr2;        
    std::cout << arr[0] << arr[1] << arr[2];   
}

与其他 C++ 标准库容器相比,std::valarray 配备了相当数量的“批量”数学运算。

【讨论】:

    【解决方案2】:

    如果在编译时使用 constexpr 函数“固定”数组也是一个好主意:

    #include <array>
    #include <iostream>
    
    //
    // Define an add function template
    // 
    // This will provide compile time checking of equal array sizes 
    // so we have no need to check that condition at runtime (over and over again).
    // 
    // By making it constexpr we can also use this function's results at compile time (See below).
    // Also by using std::array you have a good example on how C++ can return
    // arrays from functions.
    //
    // template makes the code reusable for multiple types and array sizes.
    //
    // typename type_t makes this function usable for all kinds of types so it isn't restricted to ints
    // std::size_t N allows for the compiler to generate correct code for positive array sizes
    // 
    // arr1, arr2 :
    // Passed as const because the add function should never change the content of those arrays.
    // type_t(&arr1)[N] is C++'s way of passing an array of known size 
    //     so you don't have to pass pointers, pointers to pointers and a seperate size parameter
    //     Another option would be to use std::array<type_t,N>&, but this syntax for passing arrays
    //     is very useful knowledge. 
    //
    // constexpr means, if you follow some rules you can use this function at compile time
    //     which means that the compiler will compile this function and then use it too
    // 
    // auto return type means that you let the compiler work out what type you return
    // this can help later when refactoring code. 
    // 
    
    template<typename type_t, std::size_t N>
    constexpr auto add(const type_t(&arr1)[N], const type_t(&arr2)[N])
    {
        // You can't return "C" style arrays from functions but you can return objects.
        // std::array is a wrapper object for arrays (with almost no overhead)
        // the extra {} at the end will initialize all values in the array to default value for type_t (0 for ints)
        // (one of the rules for constexpr, everything must be initialized)
        std::array<type_t, N> retval{};
    
        // a standard for loop 
        for (std::size_t n = 0; n < N; ++n) retval[n] = arr1[n] + arr2[n];
    
        // return the array, since we return a std::array<type_t,N> that will also
        // become the return type of the function (auto)
        return retval;
    }
    
    int main()
    {
        // constexpr initialization allows these arrays to be used at compile time.
        constexpr int arr[] = { 1, 2, 3 };
        constexpr int arr2[] = { 7, 4, 6 };
    
        // with constexpr ask the compiler to run add at compile time
        // (if the rules for constepxr in add do not fully apply then
        // the code will still be executed at runtime)
        constexpr auto result = add(arr, arr2);
    
        // static_assert, is like assert but then evaluated at compile time.
        // if the assert fails then teh code will not compile.
        static_assert(result[0] == 8);
        static_assert(result[1] == 6);
        static_assert(result[2] == 9);
    
        // to show you can use the results at runtime too
        bool comma{ false };
    
        // this is a range based for loop
        // using range based for loops ensures you never run out of the
        // bounds of an array (reduces bugs)
        //
        // const auto &
        // When looping over all the elements of the array
        // value will be a const reference to the current element 
        // visited. 
        // a reference to avoid copying data (not so important for ints, but important for 
        // more complex datatypes)
        // const because we are only using it, not modifying it.
        for (const auto& value : result)
        {
            if (comma) std::cout << ", ";
            std::cout << value;
            comma = true;
        }
    
        return 0;
    }
    

    【讨论】:

    • 不确定这是否超出了 OP 级别(模板?通过引用传递数组?constexpr?std::array?...)也许更多的解释会很好
    • @463035818_is_not_a_number:我非常喜欢这个 - 请记住,答案不一定需要针对 OP。
    • @Bathsheba 我记得。我喜欢这个答案。虽然我认为其他寻找添加两个数组元素的方法的人也会很高兴得到更多解释;)
    • @463035818_is_not_a_number:是的,你说得有道理。
    • 虽然 constexpr 酒窖会很伤心
    【解决方案3】:

    您将需要另一个数组来存储您的值,我们将其命名为 arr3 并使其与其他数组的大小相同。

    int arr[] = { 1,2,3 };
    int arr2[] = { 7,4,6 };
    int arr3[3]{};
    

    然后您将要添加来自 arr 和 arr2 的值并将它们放入 arr3

    arr3[0] = arr[0] + arr2[0];
    arr3[1] = arr[1] + arr2[1];
    arr3[2] = arr[2] + arr2[2];
    

    您也可以通过循环轻松做到这一点。

    for (int i = 0; i < 3; i++)
    {
        arr3[i] = arr[i] + arr2[i];
    }
    

    【讨论】:

    • 我建议不要硬编码数组的大小,而是使用类似std::size(arr)的东西。
    【解决方案4】:

    随着您对向量和矩阵的了解越来越多,您可能需要考虑使用像犰狳这样的适当代数库。在 Ubuntu 上,您只需添加

    apt get install libarmadillo-dev
    

    然后在你的 CMakeLists.txt 上

    project(arma)
    cmake_minimum_required( VERSION 3.0 )
    find_package( Armadillo REQUIRED )
    include_directories( ${ARMADILLO_INCLUDE_DIR} )
    add_executable( testarma testarma.cpp )
    

    并在您的代码中使用它

    #include <armadillo>
    #include <iostream>
    
    int main()
    {
        using vec = arma::Mat<int>;
        vec A{1, 2, 3};
        vec B{4, 5, 6};
        vec C = A + B;
        std::cout << C << std::endl;
    }
    
    $ ./testarma
       5       7        9
    

    【讨论】:

    • arma::Mat&lt;int&gt; 会不会更好?
    • 当然可以。我更改了代码以反映
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-11
    • 1970-01-01
    • 2011-11-04
    • 2012-03-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多