c++ - 由另一个数组中的值组成的数组

标签 c++ arrays multidimensional-array

如果我有一个如下所示的数组:

int map[21][28] =
{
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 2, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};

我如何创建一个由该数组中的值组成的较小数组......?
有点像这样:

int zoomedMap[7][7] =
{

    2, 2, 1, 1, 1, 1, 1,
    1, 0, 0, 0, 0, 0, 1,
    1, 0, 0, 0, 0, 0, 1,
    1, 0, 0, 0, 0, 0, 1,
    1, 0, 0, 0, 0, 0, 1,
    1, 0, 0, 0, 0, 0, 1,
    1, 1, 1, 1, 1, 1, 1
};

我不知道这是否有帮助,但是:

  • 我知道两个数组的确切尺寸
  • 我希望可以移动较小的数组位置,最好是仅更改 X/Y 值

最佳答案

希望显而易见的是,您的子数组实际上只不过是您的主数组中的一个数据“ block ”(带有一些有趣的分区)。假设您正在检查边界并且不允许发生越界情况,您可以使用指针数学和有关主数组的一些基本信息来模拟子数组。

  • 该 block 将始终是从[0][0] 位置偏移的一些[行][列],因此我们需要这些值(行和列)。
  • 该 block 具有固定宽度,因此 column+width 不会超过您的主数组宽度。我们需要那个宽度。
  • 该 block 具有固定高度,因此 row+height 不会超过您的主数组高度。我们需要那个高度。
  • 我希望很明显我们需要作为主数组的基址(在您的例子中是 map)。

这可能是最好的例子。以下不是最终的解决方案。它可能甚至无法满足您将要拥有的需求的 1/10。相反,它的目的是让您了解如何仅使用一个指针、一些偏移量、一些大小和一点算术来获得您正在寻找的东西。 没有什么可以阻止您超出可能有害的限制(就像普通数组一样),所以要小心。

// internal rerefential to a submatrix in a larger fixed matrix.
template<typename T>
class Sub2D
{
public:
    template<size_t R, size_t C>
    Sub2D(T(&ar)[R][C], int top, int left, int height, int width)
    : parent(ar[0])
    , row(top)
    , col(left)
    , max_row(R)
    , max_col(C)
    {
        if ((row+width) >= R || (col+height) >= C)
            throw std::out_of_range("");
    }

    // retrieve our subrow offset into the main 2D array
    T* operator [](size_t n)
    {
        // enable at your desire, but as Alex pointed out, all
        // the standard containers let you shoot yourself in the
        // foot with this operator. why not this one too =P
        //if (row+n >= max_row)
        //    throw std::out_of_range("");

        return parent + ((row+n)*max_col + col);
    }

private:
    T* parent;
    size_t row, col;
    size_t max_row, max_col;
};

像这样使用,假设您问题中的数组是我们基于的数组:

int main()
{
    // take the submatrix & [6][7] that is 7x7 in dimension.
    Sub2D<int> sub(map, 6,7, 7,7);
    for (size_t i=0;i<7;++i)
    {
        for (size_t j=0;j<7;++j)
            cout << sub[i][j] << ' ';
        cout << endl;
    }
    cout << endl;

    // update an element at location [1][1] of our sub-matrix.
    sub[1][1] = 9;

    // reprint the *entire* main array. it better have updated.
    for (size_t i=0;i<sizeof(map)/sizeof(map[0]);++i)
    {
        for (size_t j=0;j<sizeof(map[0])/sizeof(map[0][0]);++j)
            cout << map[i][j] << ' ';
        cout << endl;
    }
    cout << endl;

    return 0;
}

产生以下输出。

2 2 1 1 1 1 1 
1 0 0 0 0 0 1 
1 0 0 0 0 0 1 
1 0 0 0 0 0 1 
1 0 0 0 0 0 1 
1 0 0 0 0 0 1 
1 1 1 1 1 1 1 

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 2 2 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 1 9 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 

请注意 9 现在正好位于我们预期的位置。

显然,您可以向这样的模板类中添加更多内容,包括更好的范围检查、移动指针、快照到其他内存缓冲区等,但关键是基本的 get-me-this 子矩阵一个指针和几个偏移量很难被击败,尤其是在性能方面。

关于c++ - 由另一个数组中的值组成的数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14302316/

相关文章:

c++ - 我编译了最新版本的 GCC。如何将 CLion 指向它的位置?

c++ - 是否可以使用 openmp 对数组进行缩减?

php - Yii:如何从数组中设置 dropDownList 'options'

c - 为什么我的removeString函数没有删除字符?

java - 二维不同口味类型数组之间的区别?这两种类型的优点

c++ - 体系结构 x86_64 : "std::__1::locale::use_facet(std::__1::locale::id&) const" 的 undefined symbol

c++ - 如何只在一个 CPU 上运行 C++ 程序?

javascript - 创建多维数组然后将每个多维数组推送到另一个数组

javascript - 连接四个游戏逻辑

c++ - std 集合上的 CPPUNIT_ASSERT_EQUAL