【问题标题】:Best way to make a multidimensional array odd-dimensioned in C++?在 C++ 中制作奇数维多维数组的最佳方法是什么?
【发布时间】:2011-05-02 05:41:57
【问题描述】:

我编写了以下函数,通过根据需要添加行或列(其中 sizeX、sizeY、get、set 和 resize 是不言自明的 grid2D 成员函数)来制作奇维的二维数组对象。

void makeOdd(grid2D<double> *pSrc)
// ---------------------------------------------------------------------------------------------------------
// Make one or both dimensions of input array odd (via row/column copy).
{

    // Variable declarations
    grid2D<double> pTmp = *pSrc;                                // Scratch local source variable
    int simax, sjmax;                                               // Source dimensions

    // Get source dimensions
    sjmax = pSrc->sizeY();
    simax = pSrc->sizeX();

    // Check if source is already odd-dimensioned
    if (sjmax%2 && simax%2) return;

    // Extend row/column of source if necessary
    if (sjmax%2 && !(simax%2))                                      // Odd rows, even columns
    {
        pSrc->resize(simax+1,sjmax);                                // Resize source with extra column
        for(int i=0; i<simax+1; i++)
        {
            for(int j=0; j<sjmax; j++)
            {
                if(i==simax)
                    pSrc->set(i,j,pTmp.get(simax-1,j));             // Copy last column
                else
                    pSrc->set(i,j,pTmp.get(i,j));
            }
        }
        return;
    }
    else if (!(sjmax%2) && simax%2)                                 // Even rows, odd columns
    {
        pSrc->resize(simax,sjmax+1);                                // Resize source with extra row
        for(int i=0; i<simax; i++)
        {
            for(int j=0; j<sjmax+1; j++)
            {
                if(i==simax)
                    pSrc->set(i,j,pTmp.get(i,sjmax-1));             // Copy last row
                else
                    pSrc->set(i,j,pTmp.get(i,j));
            }
        }
        return;
    }
    else                                                            // Even rows, even columns
    {
        pSrc->resize(simax+1,sjmax+1);                              // Resize source with extra row and column
        for(int i=0; i<simax+1; i++)
        {
            for(int j=0; j<sjmax+1; j++)
            {
                if(i==simax && j==sjmax)
                {
                    pSrc->set(i,j,pTmp.get(simax-1,sjmax-1));       // Copy last column and row
                }
                else if(i==simax && j<sjmax)
                {
                    pSrc->set(i,j,pTmp.get(simax-1,j));             // Copy last column
                }
                else if(i<simax && j==sjmax)
                {
                    pSrc->set(i,j,pTmp.get(i,sjmax-1));             // Copy last row
                }
                else
                {
                    pSrc->set(i,j,pTmp.get(i,j));
                }
            }
        }
        return;
    }

}

我的问题:有没有更清洁/更有效的方法?

非常感谢...

【问题讨论】:

  • 你到底想在这里做什么?
  • 例如,如果我有一个尺寸为 10x10 的双精度数组 X,我想通过复制最后一行和最后一列来使 X 的尺寸为 11x11。

标签: c++ syntax multidimensional-array dimensions


【解决方案1】:

我认为首先检查行数会更容易,如果需要,可以将其扩展 1。然后,检查列数,如果需要,将每列扩展 1。

假设您的grid2dvector&lt;vector&lt;T&gt; &gt; 的包装器,您可以将一个值传递给resize,它将用于填充新创建的空间,因此当您添加一行时,您可以只传递当前的最后一个行将其复制到新的最后一行。

【讨论】:

    【解决方案2】:

    您的代码在 IMO 中对于这个问题非常复杂......我会这样做

    void makeOdd(grid2D<double> *pSrc)
    {
        int ny = pSrc->sizeY();
        int nx = pSrc->sizeX();
        int oddnx = nx + (nx % 2 == 0);
        int oddny = ny + (ny % 2 == 0);
        if (nx != oddnx || ny != oddny)
        {
            pSrc->resize(oddnx, oddny);
            if (nx != oddnx)
                for (int y=0; y<ny; y++)
                    pSrc->set(nx, y, pSrc->get(nx-1, y));
            if (ny != oddny)
                for (int x=0; x<oddnx; x++)
                    pSrc->set(x, ny, pSrc->get(x, ny-1));
        }
    }
    

    当然,取决于 grid2D,如果知道对象的内部结构而不是使用公共的 resize/get/set 接口(例如,通过将 makeOdd 设为方法),这可能会更简单。

    顺便说一句,在您的原始代码中,您正在复制一个指针(不是原始对象)的pTmp;这也是没有意义的。

    【讨论】:

    • 嗨 6502,非常感谢您提供简洁明了的代码!至于您的第二点,我在 grid2D 中定义了“=”运算符,以将 rhs 存储到一个新的 T (此处为双)容器中,因此该操作并非毫无意义。
    • 对不起,我误读了您的代码,并认为您只是在复制指针(当然您不能重载指针分配)。但是,如果调整大小操作旨在保留当前内容(如 IMO 那样),则无需复制:您只需调整大小并将元素从倒数第二列/行复制到最后一列。
    • 您好 6502,再次感谢您的回复。在我的“resize”grid2D 成员函数中,我删除了 容器并分配了一个新的指定大小的新 容器。您如何建议这样做以保留原始内容?
    • 哎呀。我认为调整大小是保留内容的(就像标准容器一样)。如果您的实现只是清除了整个内容,那么至少您应该将名称更改为recreatezap 之类的名称。如何编写有效的内容保留调整大小操作(IMO 通常非常有用)当然取决于内部表示是什么:它是具有计算索引的单个 std::vector&lt;T&gt; 还是 std::vector&lt;std::vector&lt;T&gt; &gt;?是稀疏数组std::map&lt;std::pair&lt;int, int&gt;, double&gt;
    • 容器grid2D很简单:int grid_size_x、int grid_size_y、int grid_size和T* grid(其中T通常是)。根据条件,正在存储的数据(一些遥感数据)可以是从全零到完全充满数据的任何数据。要求尽可能快地访问数据。您是否为此建议向量?
    猜你喜欢
    • 2020-08-11
    • 2021-05-20
    • 1970-01-01
    • 2015-02-26
    • 2016-11-07
    • 2013-03-03
    • 1970-01-01
    • 1970-01-01
    • 2013-08-19
    相关资源
    最近更新 更多