我如何根据C ++中的行合并两个2D数组 [英] How I can merge two 2D arrays according to row in c++

查看:82
本文介绍了我如何根据C ++中的行合并两个2D数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到一个问题,其中两个二维数组需要根据给定条件进行合并,其中 n = 5 k = 3

I am facing a problem where two 2-dimensional arrays need to merge according to the given condition, where n=5 and k=3.

第一数组->

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

结果数组->

 1 2 11 12 13 
 3 4 14 15 16 
 5 6 17 18 19
 7 8 20 21 22
 9 10 23 24 25

我对这个问题的解决方法是首先获取一个具有两个以上数组维的空二维数组,然后将两个数组元素按索引放入 ans 数组索引中。我可以将第一个数组放入 ans 数组,但是无法将第二个数组放入结果数组。它显示了插入第二个数组时出现的运行时错误。我需要帮助。

My approach to this problem is to first take an empty 2-D array of above two array dimensions, then to place two array elements into the ans array index by index. I can put the 1st array into ans array, but failed to put the 2nd array into the resultant array. It's showing a run-time error for inserting the 2nd array. I need help for that.

#include <iostream>
using namespace std;

int main()
{
    int n, k;
    cin >> n >> k;
    int p = n - k + 1, q = n - k;
    int a[n + 1][q + 1], b[n + 1][p + 1], ans[n + 1][n + 1];
    for (int i = 1; i <= n; ++i)
        for (int j = 1; j <= q; ++j)
            a[i][j] = 0;
    for (int i = 1; i <= n; ++i)
        for (int j = 1; j <= p; ++j)
            b[i][j] = 0;
    for (int i = 1; i <= n; ++i)
        for (int j = 1; j <= n; ++j)
            ans[i][j] = 0;

    int x = 1;
    for (int i = 1; i <= n; ++i)
    {
        for (int j = 1; j <= q; ++j)
            a[i][j] = x++;
    }
    for (int i = 1; i <= n; ++i)
    {
        for (int j = 1; j <= p; ++j)
            b[i][j] = x++;
    }
    for (int i = 1; i <= n; ++i)
    {
        for (int j = 1; j <= q; ++j)
            ans[i][j] = a[i][j];
    }
    int I = 1, J = 0;
    for (int i = 1; i <= n; ++i)
    {
        I += 2, J++;
        for (int j = 1; j <= p; ++j)
        {
            ans[I][J] = b[i][j];
            I++;
        }
    }
    for (int i = 1; i <= n; ++i)
    {
        for (int j = 1; j <= q; ++j)
            cout << a[i][j] << " ";
        cout << endl;
    }
    for (int i = 1; i <= n; ++i)
    {
        for (int j = 1; j <= p; ++j)
            cout << b[i][j] << " ";
        cout << endl;
    }
    for (int i = 1; i <= n; ++i)
    {
        for (int j = 1; j <= n; ++j)
            cout << ans[i][j] << " ";
        cout << endl;
    }

    return 0;
}


推荐答案

其中有三个主要问题发布的代码

There are three main issues in the posted code


  • a b ans 被声明为可变长度数组(它们的大小在编译时未知),即非标准扩展。 OP可能使用了 std :: vector 之类的标准容器或用户定义的类。

  • a, b and ans are declared as variable length arrays (their sizes aren't known at compile time), a non-standard extension provided by some compilers. The OP could have used a standard container like std::vector or a user-defined class.

所有循环都从1开始,而在C ++数组中,索引是从0开始的。这段代码的作者似乎知道这一事实,但是出于某种原因,它倾向于在所有数组中分配额外的(未使用的)空间,并相应地适应终止条件。

All the loops start at 1, while in C++ array indices are 0-based. The writer of this code seems to know this fact, but for some reason preferred to allocate extra (unused) space in all the arrays and to accomodate the termitation conditions accordingly.

试图将值从 b 复制到 ans 的嵌套循环是完全错误的,并导致多次访问范围。

The nested loop which tries to copy the values from b to ans is simply wrong and causes multiple accesses out of bounds.

int I = 1, J = 0;                     // --->  I = 0, keeping OP's convention
for (int i = 1; i <= n; ++i)
{
    I += 2, J++;                      // --->  ++I, J = q
    for (int j = 1; j <= p; ++j)
    {
        ans[I][J] = b[i][j];
        I++;                          // ---> ++J
    }
}


下面的代码片段显示了一个替代实现,其中使用一个类对矩阵进行建模,然后 merge 函数执行所需的操作。

In the following snippet shows an alternative implementation where the matrices are modelled using a class and the merge function performs the wanted operation.

#include <algorithm>
#include <iomanip>
#include <iostream>
#include <numeric>
#include <stdexcept>
#include <vector>

template <class T>
class Matrix
{
    size_t rows_{};
    size_t cols_{};
    std::vector<T> m_;
public:
    Matrix() = default;
    Matrix(size_t r, size_t c)
        : rows_{r}, cols_{c}, m_(r * c)
    {}

    auto rows() const noexcept {
        return rows_;
    }
    auto columns() const noexcept {
        return cols_;
    }
    auto operator[] (size_t i) noexcept {
        return m_.begin() + cols_ * i;
    }
    auto operator[] (size_t i) const noexcept {
        return m_.cbegin() + cols_ * i;
    }
    auto begin() noexcept {
        return m_.begin();
    }
    auto end() noexcept {
        return m_.end();
    }
};

template <class T>
std::ostream& operator<< (std::ostream& os, Matrix<T> const& m)
{
    for (size_t i{}; i < m.rows(); ++i)
    {
        for (size_t j{}; j < m.columns(); ++j)
            os << m[i][j] << ' ';
        os << '\n';
    }
    return os;
}

template<class T>
auto merge(Matrix<T> const& a, Matrix<T> const& b)
{
    if (a.rows() != b.rows())
        throw std::runtime_error{"Number of rows mismatch"};

    Matrix<T> result(a.rows(), a.columns() + b.columns());

    for (size_t i{}; i < a.rows(); ++i)
    {
        auto it = std::copy(a[i], a[i] + a.columns(), result[i]);
        std::copy(b[i], b[i] + b.columns(), it);
    }

    return result;
}


int main()
{
    int n, k;
    std::cin >> n >> k;
    int p = n - k + 1, q = n - k;

    Matrix<int> a(n, q);
    std::iota(a.begin(), a.end(), 1);
    std::cout << a << '\n';

    Matrix<int> b(n, p);
    std::iota(b.begin(), b.end(), n * q + 1);
    std::cout << b << '\n';

    auto c = merge(a, b);
    std::cout << c << '\n';
}

这篇关于我如何根据C ++中的行合并两个2D数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆