If you are interested in storage, you might consider using a small matrix of storage formats to store the resulting matrix, and then release the original input density.
An example of what I propose could be the following (using the COO format), which should take O (M * N) time:
#include<vector> #include<iostream> #include<algorithm> #include<cstddef> using namespace std; int main() { constexpr size_t M = 3; constexpr size_t N = 3; int matrix[M][N] = { {1, 2, 3}, {0, 4, 5}, {4, 2, 0} }; vector<size_t> markedRows; vector<size_t> markedColumns; // Search for zeroes for (size_t ii = 0; ii < M; ++ii) { for(size_t jj = 0; jj < N; ++jj) { if (matrix[ii][jj] == 0) { markedRows.push_back (ii); markedColumns.push_back(jj); } } } // Sort columns (rows are ordered by construction) sort(markedColumns.begin(),markedColumns.end()); // Eliminate duplicates markedRows.erase (unique(markedRows.begin() ,markedRows.end()) ,markedRows.end() ); markedColumns.erase(unique(markedColumns.begin(),markedColumns.end()),markedColumns.end()); // Construct COO matrix format vector<size_t> irow; vector<size_t> icol; vector<int> val; for (size_t ii = 0; ii < M; ++ii) { for(size_t jj = 0; jj < N; ++jj) { if ( ( find(markedRows.begin() ,markedRows.end() ,ii) == markedRows.end() ) && ( find(markedColumns.begin(),markedColumns.end(),jj) == markedColumns.end() ) ) { irow.push_back(ii); icol.push_back(jj); val.push_back (matrix[ii][jj]); } } } // FROM HERE YOU NO LONGER NEED MATRIX, AND YOU CAN FREE THE STORAGE // Print non zero entries for( size_t ii = 0; ii < irow.size(); ++ii) { cout << "A["<<irow[ii]<<","<<icol[ii]<<"] = "<<val[ii]<<endl; } return 0; }
source share