Home > Mobile >  erase rows and colums of a 2D vector, when a condition is achieved in another single vector?
erase rows and colums of a 2D vector, when a condition is achieved in another single vector?

Time:11-30

I have a matrix (vector of vector), in other words, 2D vector (6 X 6) elements <double>, and after I have a vector with 6 elements <int>. the vector with ints has only "0" and "1". Then, I am looking for a way to remove a row and column of the 2D vector when a "0" is found in the vector (1D) of ints. This time is only 6 X 6 but later on, will be around 100 X 100.

What I've done is use iterators, and I successfully remove the rows but now I don't know how to tackle the columns.

This is my code.

#include <iostream>
#include <vector>
#include <iomanip>

int main() {

    std::vector <int> boundaryConditions = { 0,1,1,1,0,0 };
    std::vector <std::vector<double>> matrix = { {1.46371e 07, 1.46371e 07, -1.46371e 07, -1.46371e 07, 0, 0},
    {1.46371e 07, 5.60371e 07, -1.46371e 07, -1.46371e 07, 0, -4.14e 07},
    {-1.46371e 07, -1.46371e 07, 5.60371e 07, 1.46371e 07, -4.14e 07, 0},
    {-1.46371e 07, -1.46371e 07, 1.46371e 07, 1.46371e 07, 0, 0},
    {0, 0, -4.14e 07, 0, 4.14e 07, 0},
    {0, -4.14e 07, 0, 0, 0, 4.14e 07}};

    int i = 0;
    std::vector<int>::iterator it = boundaryConditions.begin();
    while (it != boundaryConditions.end())
    {
        if (*it == 0)
        {
            it = boundaryConditions.erase(it);
            matrix.erase(matrix.begin()   i);
        }
        else
        {
            it  ;
            i  ;
        }
    }

    for (int i = 0; i < matrix.size(); i  )
    {
        for (int j = 0; j < matrix[i].size(); j  )
        {
            std::cout << matrix[i][j] << std::setw(15);
        }
        std::cout << "\n";
    }
    system("pause>0");
}

CodePudding user response:

Maybe this could help, not fully tested: Let A be the binaryConditions array,

void reduce(std::vector<int> A, std::vector<int> &target) {
    int i = 0, j = 0;
    int nOnes = 0;
    while (i<A.size() && j < A.size()) {
        if (A[i] != 0) {
              i;
            nOnes  ;
        }
        else {
            j = max(i   1, j);
            while (j < A.size() && A[j] == 0)   j;
            if (j >= A.size()) break;
            swap(A[i], A[j]);
            swap(target[i], target[j]);
        }
    }
    A.resize(nOnes);
    target.resize(nOnes);
}

CodePudding user response:

You can create a new matrix after you've removed the rows.

std::vector<std::vector<double>> removeColumns(const std::vector<int>& boundaryConditions, 
                                               const std::vector<std::vector<double>>& matrix)
{
    std::vector<std::vector<double>> returnValue(matrix.size());
    size_t curRow = 0;
    size_t curCol = 0;
    for (auto& v : returnValue)
    {
        for (size_t curCol = 0; curCol < matrix[0].size();   curCol)
        {
              if (boundaryConditions[curCol] == 1)
                  v.push_back(matrix[curRow][curCol]);
        }
          curRow;
    }
    return returnValue;
}

Then you would call it like this, given that you have already removed the rows from matrix:

matrix = removeColumns({0,1,1,1,0,0}, matrix); 

Here is a Live Example.


If you want an in-place solution, here is an example:

void removeColumns(const std::vector<int>& boundaryConditions, std::vector<std::vector<double>>& matrix)
{
    size_t curCol = 0;
    for (size_t i = 0; i < boundaryConditions.size();   i)
    {
        if (boundaryConditions[i] == 0)
        {
            for (auto& v : matrix)
               v.erase(v.begin()   curCol);
        }
        else
            curCol;
    }            
}

Then it would be called like this:

removeColumns({0,1,1,1,0,0}, matrix);

Here is a Live Example

  • Related