Лучший способ сделать многомерный массив нечетным в C ++? - PullRequest
1 голос
/ 02 мая 2011

Я написал следующую функцию, чтобы сделать объект двумерного массива нечетным, добавив нужную строку или столбец (где 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;
    }

}

Мой вопрос: есть ли более чистый / более эффективный способ сделать это?

Большое спасибо ...

Ответы [ 2 ]

1 голос
/ 02 мая 2011

Ваш код 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 указателя (а не исходного объекта); и это тоже бессмысленно.

1 голос
/ 02 мая 2011

Я думаю, что было бы проще сначала проверить количество строк и увеличить их на 1, если это необходимо.Затем проверьте количество столбцов и при необходимости увеличьте каждый из них на 1.

Предполагая, что grid2d является оберткой вокруг vector<vector<T> >, вы можете передать значение resize, чтоиспользуется для заполнения вновь созданного пространства, поэтому при добавлении строки вы можете просто передать текущую последнюю строку, чтобы скопировать ее в новую последнюю строку.

...