3D Array to 3D std::vector - c++

I replaced a 3D array with a 3D std::vector in my code function and it's entering a infinite loop .Could you give me a hint,I really need to use a vector instead an array.Thanks:)
My initial code was:
//arr is a 3D array of a sudoku table,the 3 rd dimension is for keeping values 0 to 13
//for a cell, and when I assign values I start from index 1 to 12
bool sol(int arr[12][12][13]) {
int row,col;
if(!find_empty(arr,row,col)) return true;
for(int i=1;i< 12;i++) { //for digits 1 to 12
if(is_working(arr,row,col,arr[row][col][i]) ) { //if i can put the value in a cell
arr[row][col][0] = arr[row][col][i]; //replace the first element for a cell with that value
//here I want to use vector because I want to use an ac3 algorithm
//and remove those values that not satisfy constraints and shrink domain size having less values to verify with backtrack
if(sol(arr)) return true;
arr[row][col][0] = 0;
}
}
return false;//if not backtrack
}
I replace arr with:
std::vector<std::vector<std::vector<int> > > vec;
vec.resize(12);
for(int i=0;i<12;i++)
{
vec[i].resize(12);
for(int j=0;j<12;j++)
{
vec[i][j].resize(13);
for(int k=0;k<13;k++)
vec[i][j][k]=table[i][j][k];
}
}
bool sol(std::vector<std::vector<std::vector<int> > >& vec) {
int row,col;
if(!find_empty(vec,row,col)) return true;
for(int i=1;i< vec[row][col].size();i++) {//for remainig values in domain
if(is_working(vec,row,col,vec[row][col][i]) ) {//same as above but having less values to verify for
vec[row][col][0] = vec[row][col][i];
if(sol(vec)) return true;
vec[row][col][0] = 0;
}
}
return false;
}
and now it's entering a infinite loop!The initial code has no errors,it's a simple backtracking.The problem appears after I replace arr with vec.Could you give me some advice on how to replace 3D arr with an 3D vector

Your question is not clear enough. If you can also post the code for is_working and find_empty, then we would be able to see how you are getting the values of row and column.
I would have put this as a comment but being a new member and not having enough reputations, I have to put this as an answer. I'll edit it once you share the code for is_working() and find_empty()

I have solved the problem. I used a matrix of vectors instead a 3D vector and it works great :D
maybe this better for 3d one, 4x4x4
std::vector<std::vector<std::vector<double>>> matrix;
matrix.resize(4, std::vector<std::vector<double>>(4,std::vector<double(4)));

Related

match elements between two std::vectors

I am writing a module that estimates optical flow. At each time step it consumes an std::vector where each element of the vector is a current pixel location and a previous pixel location. The vector is not ordered. New pixels that were previously not seen will be present and flow locations that were not found will be gone. Is there a correct way to match elements in the new vector to the set of optical flow locations being estimated?
The vectors are on the order of 2000 elements.
These are the approaches I am considering:
naively iterate through the new vector for each estimated optical flow location
naively iterating through the new vector but removing each matched location so the search gets faster as it goes on
run std::sort on my list and the new list at every time step. Then iterate through the new vector starting at the last matched index +1
I'm suspecting that there is an accepted way to go about this but I don't have any comp sci training.
I'm in c++ 11 if that is relevant.
// each element in the new vector is an int. I need to check if
// there are matches between the new vec and old vec
void Matcher::matchOpticalFlowNaive(std::vector<int> new_vec)
{
for(int i = 0; i < this->old_vec.size(); i++)
for(int j =0; j < new_vec.size(); j++)
if(this->old_vec[i] == new_vec[j]){
do_stuff(this->old_vec[i], new_vec[j])
j = new_vec.size();
}
}
Not sure to understand what do you need but, supposing that your Matcher is constructed with a vector of integer, that there ins't important the order and that you need check this vector with other vectors (method matchOpticalFlowNaive()) to do something when there is a match, I suppose you can write something as follows
struct Matcher
{
std::set<int> oldSet;
Matcher (std::vector<int> const & oldVect)
: oldSet{oldVect.cbegin(), oldVect.cend()}
{ }
void matchOpticalFlowNaive (std::vector<int> const & newVec)
{
for ( auto const & vi : newVec )
{
if ( oldSet.cend() != oldSet.find(vi) )
/* do something */ ;
}
}
};
where the Matcher object is constructed with a vector that is used to initialize a std::set (or a std::multi_set, or a unordered set/multiset?) to make simple the work in matchOpticalFlowNaive()

Inserting values to a multidimensional-vector in C++

I've got a minor problem.
I'm using multidimensional-vectors and I want to insert some values to it at a given position. I'm making a sudoku in wxWidgets and i'm getting the tiles the player have put in and wanting to store them in my mVector.
The mVector looks like this.
vector< vector<string> > board{9, vector<string>(9)};
And at first i've added values just like this.
board[row][col] = value;
"value" is a string and row/col are ints.
Is this a legit way of adding values to the mVector? I'm asking this because when I update the board, by doing this above, I for some reason can't run my other functions where i'm solving the board, giving a hint to the board and so on. Before i store the new values to it all the functions works correkt. Do I maby need to use some other type of build in functions for the vector like insert, push_back or something instead?
Since you declared the vector as size 9x9, yes that is a valid way of assigning values.
Otherwise you could declare the board as
vector<vector<string>> board;
Then fill it with
for (int i = 0; i < 9; ++i)
{
vector<string> row;
for (int j = 0; j < 9; ++j)
{
row.push_back(value); // where value is whatever you want
}
board.push_back(row);
}
But again, once the board is of size 9x9, you can simply assign a value at any cell for example
board[2][4] = "hello";
Working example

c++ matrix insert value using iterators (homework)

I'm pretty new to C++ and got an assignment to make a matrix using only STL containers. I've used a vector (rows) of vectors (columns). The problem I'm having is in the 'write' operation - for which I may only use an iterator-based implementation. Problem is, quite simply: it writes nothing.
I've tested with a matrix filled with different values, and while the iterator ends up on exactly the right spot, it doesn't change the value.
Here's my code:
void write(matrix mat, int row, int col, int input)
{
assert(row>=0 && col>=0);
assert(row<=mat.R && col<=mat.C);
//I set up the iterators.
vector<vector<int> >::iterator rowit;
vector<int>::iterator colit;
rowit = mat.rows.begin();
//I go to the row.
for(int i = 0; i<row-1; ++i)
{
++rowit;
}
colit = rowit->begin();
//I go to the column.
for(int j = 0; j<col-1; ++j)
{
++colit;
}
*colit = input; //Does nothing.
}
What am I overlooking?
Thanks.
matrix mat is a parameter by value, it copies the matrix and hence you are writing to a copy.
You should pass the matrix by reference instead, like matrix & mat.
But wait... You are passing the matrix every time as the first parameter, this is a bad sign!
This usually indicates that the parameter should be turned into an object on which you can run the methods; that way, you don't need to pass the parameter at all. So, create a Matrix class instead.
Please note that there is std::vector::operator[].
So, you could just do it like this:
void write(matrix & mat, int row, int col, int input)
{
assert(row>=0 && col>=0);
assert(row<=mat.R && col<=mat.C);
mat[row][col] = input;
}

Maximum matching in a graph

I have an interesting problem:
My program must to find the maximum number of 1.
But that's not all!.
If the program has "seen" 1, then it should clear the entire column and row in which the 1 is located.
The problem I have:
I can not find the maximum number of 1, I do not know how to do that.
For you I made a small example, I hope it will be clear to you. The program must work like this:
There is a matrix:
1 0 0 0
1 0 1 1
1 1 1 1
1 0 0 1
The program found 1 (position [0][0] I've highlighted it in black), and cleared the row and column:
After this we find the next 1, cleared the row and columnand so on:
At the end, the program should print the number of black cells.
In my example it's 4
How to do it in C++ code? Please help me! Thank you.
I prefer to do it like this (see code below): Use two "for" loops and inside the second use conditional "if" to add the third "for" loop to set to 0.
for(int i=0;i<m;i++)
for(int j=0;j<n;j++)
{
if(cow[j][i]==1)
{
cnt++;
for(int k=0;k<n;k++)
cow[k][i]=cow[j][k]=0;
break;
}
}
it's not clear how you search for the 'next' 1 in your matrix and if the matrix can only contain 0 and 1. But if there is a clear definition of what 'next' is, then you just code exactly as you have described it above. A possible code snippet looks like this (not tested, not even compiled):
bool find_next_one(int&x, int&y, matrix const&M)
{
// next is in (col,row) order
for(; x!=M.size(0); ++x)
for(; y!=M.size(1); ++y)
if(M(x,y)==1) return 1;
return 0;
}
int count_one(matrix const&M_original)
{
matrix M(M_original); // make copy where we can set elements to 0
int count=0;
int x=0,y=0;
while(find_next_one(x,y,M)) {
++count;
for(int i=0; i!=M.size(1); ++i) M(x,i) = 0;
for(int i=0; i!=M.size(0); ++i) M(i,y) = 0;
}
return count;
}
Noticed this looks like a matrix singularity type check - especially if 1s and 0s are the only thing to be used.
You can check the determinate of the matrix. Non zero means it is equal to the number of rows and columns (if the matrix is always square.) If det(0), then use any technique you want to bring the matrix down to reduced form to see how many 0'd columns you have - or just do the reduction first and walk down the diagonal counting.
Heck sorting the columns by their added value, will put it in diagonal form for you. That would make it pretty easy also to check for 0 columns.
I won't write all the code for you, but will suggest some things to get you on track. You should understand how to iterate over a two dimensional array (the matrix) and also how to iterate over a single row or column within that matrix.
Given a (hard coded) definition of matrix that looks like this:
struct Matrix4x4
{
int m[4][4];
};
To iterate over all elements you want to write something like this:
Matrix4x4 matrix;
for (size_t row = 0; row < 4; ++row)
{
for (size_t col = 0; col < 4; ++col)
{
// do something with 'matrix.m[row][col]'
}
}
This will iterate over your matrix from top left (0,0) to bottom right (3,3). I am assuming that this is the traversal order you have been told to use.
To process a row you want to write something like this:
void FunctionThatOperatesOnARow(Matrix4x4& matrix, size_t row)
{
for (size_t col = 0; col < 4; ++col)
{
// do something with 'matrix.m[row][col]'
}
}
To process a column you want to write something like this:
void FunctionThatOperatesOnAColumn(Matrix4x4& matrix, size_t col)
{
for (size_t row = 0; row < 4; ++row)
{
// do something with 'matrix.m[row][col]'
}
}
What you need to do now is modify the first bit of code that iterates over all elements and get it to check for a 1. You then need to call the appropriate functions to clear the current column and row (which you can base on the latter two examples).
For the final result you can simply increment a local counter variable each time you detect a 1.

Deleting from vector in for loop crashes?

I'm having a problem with my looping over a vector, and deleting values from another vector sometimes crashes my program. I have this vector of int's to keep track of which elements should be removed.
std::vector<int> trEn;
Then I loop through this vector:
struct enemyStruct {
float x, y, health, mhealth, speed, turnspeed;
double angle, tangle;
};
std::vector<enemyStruct> enemies;
The loop looks like this:
for ( unsigned int i = 0; i < bullets.size(); i++ ) {
for ( unsigned int j = 0; j < enemies.size(); j++ ) {
if ( bullets[i].x > enemies[j].x-10 && bullets[i].x < enemies[j].x+10 && bullets[i].y > enemies[j].y-10 && bullets[i].y < enemies[j].y+10 )
{
enemies[j].health-=bullets[i].dmg;
if(enemies[j].health<=0){trEn.push_back(j);break;}
}
}
}
The bullets vector is just another vector similar to the enemies vector, but with bullets in it. That one does not seem to be the problem. All this code works well, but when it comes to actually delete the items in my enemies vector the program sometimes crashes.
std::reverse( trEn.begin(), trEn.end() );
for ( unsigned int g = 0; g < trEn.size(); g++ ) {
unsigned int atmp = trEn.at(g);
if(atmp<=enemies.size()&&atmp>=0)enemies.erase(enemies.begin()+atmp,enemies.begin()+atmp+1);
} trEn.clear();
First I reverse the vector of int´s so that it will go from back to front. If i did´nt do this all values after trEn[0] would be invalid.
This is the loop which gives me a crash, but only sometimes. What I´m trying to do is a top-down shooter game, and it seems that when lots of things should be removed at the same time it just crashes. Please help me with this!
Just ask if I was unclear or if there is anything missing.
The only seemingly obvious thing would be:
if(atmp<=enemies.size() ...
Are you sure you do not mean (atmp < enemies.size()) here? Otherwise your code
enemies.erase(enemies.begin()+atmp, ...
will for sure produce some serious issues.
Your first code sample are two nested loops - you iterate over bullets and for each bullet you iterate over enemies adding enemy indices to trEn vector. What makes you think that contents of trEn are sorted in ascending order after that? For first bullet you can add index 3, and for the second index 2. You can even add same index for different bullets. Or am I missing something?