简体   繁体   中英

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

I have a basic 2d array in c++. I want to delete a specific column and place the next column in its place. my array is NAME[ ] TMARKS[ ] FNAME[ ] REG#[ ]
Name and FNAME are in 1st 2d array(string) while Tmarks and reg # are in 2nd 2d array(int)

I already tried a solution on StackOverflow but not working.

#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.

Now I want to make a function which deletes a single column.

It is not possible to "delete" elements of an array. The size of an array is constant. It remains the same from the beginning of its lifetime until it is destroyed. C++ does offer a resizable dynamic array data structure by the name std::vector .

What you may do is copy the contents of the successive elements onto their preceding sibling. There is actually a standard algorithm for this: std::rotate . Rotate does however preserve the value of all elements; the one that is written over is rotated to the end. This isn't necessarily what you need, so as a minor optimisation, you could write your own algorithm that doesn't do that.

For a multi-dimensional array, you need to repeat this algorithm for each row.

You can not remove a column from an array. But you can move all elements of columns to the left filling the "deleted" column and keep the number of actual columns of the array.

Here is a demonstrative program. In the program the variable n stores the number of actual columns of a two-dimensional array.

#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;
}

The program output is

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 

Or the function can be defined the following more simpler way

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;
}

In this case the header <type_traits> is redundant.

Also instead of the algorithm std::copy you could use the algorithm std::move .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM