如何在 C++ 中删除二维数组中的列

How to delete a column in 2d array in c++

我有一个基本的 C++ 二维数组。我想删除一个特定的列并将下一列放在它的位置。我的数组是 名称[ ] 商标[ ] FNAME[ ] REG#[ ]
名称和 FNAME 在第一个二维数组(字符串)中,而 Tmarks 和 reg # 在第二个二维数组(int)中

我已经在 Whosebug 上尝试了一个解决方案,但没有用。

#include <iostream>
using namespace std;
#define ROW 2
#define COL 70
void input(string data[][COL], int moredata[][COL], int n)
{
    for (int i = 0; i < ROW; i++)
    {
    for (int j = 0; j < n; j++)
    {
        if (i == 0)
        {
            cout << " Name of Student #  : " << j + 1 << endl;
            cin >> data[i][j];
            cout << "Total Marks out of 600 of student #  " << j + 1 <<
            endl;            
            cin >> moredata[i][j];
        }
        if (i == 1)
        {
            cout << " Father Name of Student # " << j + 1 << endl;
            cin >> data[i][j];
            cout << "Reg # of student # " << j + 1 << endl;
            cin >> moredata[i][j];
        }
     }
     }
}
int main()
{
int n;
string data[ROW][COL] = {};
int moredata[ROW][COL] = {};
cout << "NO of Students: ";
do
{
    cin >> n;
} while (n > 70 || n < 0);
input(data, moredata, n); //input function already created.

现在我想创建一个删除单个列的函数。

无法 "delete" 个数组元素。数组的大小是恒定的。它从它的生命周期开始一直保持不变,直到它被摧毁。 C++ 确实提供了一个名为 std::vector.

的可调整大小的动态数组数据结构

你可以做的是将连续元素的内容复制到它们前面的兄弟元素上。实际上有一个标准算法:std::rotate。然而,Rotate 确实保留了所有元素的值;被覆盖的旋转到最后。这不一定是你需要的,所以作为一个小的优化,你可以编写你自己的算法,而不是这样做。

对于多维数组,您需要对每一行重复此算法。

您不能从数组中删除列。但是您可以将列的所有元素移动到左侧填充 "deleted" 列并保留数组的实际列数。

这是一个演示程序。在程序中,变量 n 存储 two-dimensional 数组的实际列数。

#include <iostream>
#include <string>
#include <type_traits>
#include <iterator>
#include <algorithm>

template <typename T>
bool remove_column( T &a, size_t n, size_t pos )
{
    const size_t N = 
        std::extent<typename std::remove_reference<decltype( a )>::type, 1>::value;

    bool success = n <= N && pos < n;

    if ( success )
    {
        for ( auto &row : a )
        {
            std::copy( std::next( std::begin( row ), pos + 1 ), 
                       std::next( std::begin( row ), n ),
                       std::next( std::begin( row ), pos ) );
        }
    }

    return success;
}

int main() 
{
    const size_t M = 4;
    const size_t N = 5;
    std::string a[M][N] =
    {
        { "A0", "B0", "C0", "D0", "E0" },
        { "A1", "B1", "C1", "D1", "E1" },
        { "A2", "B2", "C2", "D2", "E2" },
        { "A3", "B3", "C3", "D3", "E3" },
    };

    size_t n = N;

    for ( const auto &row : a )
    {
        for ( size_t i = 0; i < n; i++ )
        {
            std::cout << row[i] << ' ';
        }
        std::cout << '\n';
    }

    std::cout << '\n';

    if ( remove_column( a, n, 0 ) ) --n;

    for ( const auto &row : a )
    {
        for ( size_t i = 0; i < n; i++ )
        {
            std::cout << row[i] << ' ';
        }
        std::cout << '\n';
    }

    std::cout << '\n';

    if ( remove_column( a, n, n - 1 ) ) --n;

    for ( const auto &row : a )
    {
        for ( size_t i = 0; i < n; i++ )
        {
            std::cout << row[i] << ' ';
        }
        std::cout << '\n';
    }

    std::cout << '\n';

    if ( remove_column( a, n, 1 ) ) --n;

    for ( const auto &row : a )
    {
        for ( size_t i = 0; i < n; i++ )
        {
            std::cout << row[i] << ' ';
        }
        std::cout << '\n';
    }

    std::cout << '\n';

    return 0;
}

程序输出为

A0 B0 C0 D0 E0 
A1 B1 C1 D1 E1 
A2 B2 C2 D2 E2 
A3 B3 C3 D3 E3 


B0 C0 D0 E0 
B1 C1 D1 E1 
B2 C2 D2 E2 
B3 C3 D3 E3 


B0 C0 D0 
B1 C1 D1 
B2 C2 D2 
B3 C3 D3 


B0 D0 
B1 D1 
B2 D2 
B3 D3 

或者函数可以定义成下面更简单的方式

template <typename T, size_t M, size_t N>
bool remove_column( T ( &a )[M][N], size_t n, size_t pos )
{
    bool success = n <= N && pos < n;

    if ( success )
    {
        for ( auto &row : a )
        {
            std::copy( std::next( std::begin( row ), pos + 1 ), 
                       std::next( std::begin( row ), n ),
                       std::next( std::begin( row ), pos ) );
        }
    }

    return success;
}

在这种情况下,header <type_traits> 是多余的。

您还可以使用算法 std::move.

而不是算法 std::copy