how to add elements to front of 2d vector - c++

I have a game that creates a random string of letters and then inputs it to a 2d vector. I was oringally using an array and it filled the array with random letters as it should, but the array was giving me some problems. My friend suggested a 2d array.
Here is the print function that gives me the error that actually causes a break in the program:
const vector<vector<char>>& Board::get_board()
{
for (int i = 0; i < 16; i++)
{
letters.insert(letters.begin(), 1, random_letter());
}
uppercase(letters);
random_shuffle(letters.begin(), letters.end());
int counter = 0;
for (size_t i = 0; i < 4; i++){
for (size_t j = 0; j < 4; j++)
{
board[0].push_back(letters[counter++]);
}
}
I keep getting the array to fill the first row, but then it throws an exception. I'm not sure what the exception is, but when I try to move forward, it tells me the code exited with exception 0 and points to the board[][] line in the print method. I don't think the second vector is being filled. How can I do this? Should I make another temp vector, or use a pair method? I tried the pair method before without much success.
I just changed the 0 to i and indeed, that solved the issue. Thanks! I think that I was thinking the vector would just push to the front counter number of times, not that we had 2 dimensions where the board[i] set the row. Thanks again. Silly error.

Your vector isn't being populated correctly in your get_board() method:
board[0].push_back(letters[counter]);
You're always pushing back onto the first element, but then you use it with the expectation that the board vector has 4 entries in it with the print() method. You also never increment counter and so you always push back the same letter...
Okay, based on comments, you've said you fixed how populate to something more like?
int counter = 0;
for (size_t i = 0; i < 4; i++){
for (size_t j = 0; j < 4; j++)
{
board[i].push_back(letters[counter++]);
}
}
I also don't see the point of the if statement in the print() method.

Related

understanding what this line of code does

So I'm supposed to write a function that deletes a duplicate and was having a hard time understanding a certain line.
void repeat(char arr[], int times[],int &arraySize)
{
{
for(int i = 0; i<arraySize; i++)
{
for(int j =i+1; j<arraySize; j++)
{
if(arr[i]==arr[j])
{
for(int c = j; c < arraySize-1; c++){
arr[c] = arr[c+1];
}
arraySize--;
}
}
}
}
}
***for(int c = j; c < arraySize-1; c++){
arr[c] = arr[c+1];***
Are these lines looping through all the way to the last element of the array? Also a bit confused about arr[c] = arr[c+1]; why do we need that?
To delete an element in an array (whether duplicate or not -- that's irrelevant) you have to move all of the remaining elements one position down, to cover the element being deleted. And when we say 'move' we actually mean 'copy'.
So, the loop that you see replaces each element from j to arraySize - 1 with the element immediately following it. The last element does not need to be replaced, and in fact is not replaced, because the statement arraySize--; ensures that it will never be considered again.
(Also, if you think about it, if it was to be replaced, what would it be replaced with? There is no element at position [arraySize]! C++ arrays are indexed from zero, so the valid elements are from [0] to [arraySize - 1].)

Using comparison operators to sort string array

I looked everywhere and I could not find a concrete answer that suits my needs. I want use this type of format to sort a more complicated array than this example. It compiles, but when I run it I get the terminated by signal SIGSEV (address boundary error).
A simple example of what I am trying to do:
string array[] = {zipper, bad, dog, apple, car};
string temparray[5];
int counter = 0;
for(int i = 0; i < 5; i++){
for(int x = 0; x < 5; x++){
if(array[i] > array[x]){
counter++;
}
}
temparray[counter] = array[i];
}
for(int y = 0; y < 5; y++){
array[y] = temparray[y];
}
What seems to be the problem?
You never reset counter. Suppose that your array is {5,4,3,2,1}. Then after the first iteration of the for loop, you'd have counter=4. After the next iteration of the inner for loop, counter would be 7, and you'd be trying to access the 7th element in temparray on your line
temparray[counter] = array[i];
but temparray is only 5 elements long. I don't offhand know how the > and < operators work for std::string's, but I'd bet oaks to acorns this is your problem.
You can fix this just by adding
counter=0;
directly after the aforementioned line:
temparray[counter] = array[i];
or by initializing it to zero at the start of the loop, or declaring it in the loop or what have you.

Initializing a member vector<vector<int>> in the constructor value-by-value

I have a class that should generate a 2D vector of ints (in the range of 0-1) that I want to use as a map (called matrix).
class generator
{
public:
void draw(void);
void iterate(void);
generator();
~generator();
private:
vector<vector<int>> matrix;
};
In the constructor I want to fill the matrix with random data:
vector<vector<int>> matrix(height, vector<int>(width));
for (int i = 0; i < height; i++){
for (int j = 0; j < width; j++) {
matrix[i][j] = rand() % 2;
}
}
But I get a read acess violation.
Thank you for your time and effort.
DEPRECATED UPDATE:
I tried using the member function .data() to retrieve the pointer to the data and accessing it directly
ptr = matrix[i][j].data();
*ptr = rand() % 2;
But the result doesn't differ. I'm fairly convinced that this isn't about how I want to access the vector but how I set it up.
UPDATE 2:
The correction provided below does result in the vector being filled as intended. When trying to
cout << matrix[i][j];
in the draw member function I get a read-acess-violation again.
UPDATE 3:
As suggested I checked when exactly this error happens. It happens on the very first try do print out the first integer at matrix[0][0]. The value returned is 0x8. Important: If not replaced by a constant matrix.size() already causes the error.
UPDATE 4:
This is basically my draw()
void generator::draw() {
for (int i = 0; i < matrix.size(); i++) {
for (int j = 0; j < matrix[i].size(); j++) {
cout << matrix[i][j];
}
cout << endl;
}
}
The original source has been updated to reflect the current one.
UPDATE 4:
Slightly cut source code at http://pastebin.com/83vrDJWZ
UPDATE 5:
One more simple mistake on my part has been resolved in the comments. Problem is silved. Thank you all.
Looks like the problem is an invalid pointer due to:
vector<vector<int>*> matrix;
You have a vector of pointers to vector of int, but you never actually allocate the inner elements.
Instead use:
vector<vector<int>> matrix;
And during the initialization steps:
matrix[i].resize(width); // instead of: matrix[i]->resize(width);
Actually, you could simplify it a bit:
std::vector<std::vector<int>> matrix(height, std::vector<int>(width));
Still have to iterate to fill the data, though.

C++ Vector of vectors, cannot edit

I have a MatrixGraph class with a member variable M that is of type vector<vector<double> >. I have a constructor that takes in an unsigned, and makes a NxN matrix from that input, and I want to initialize it to zero. The problem is when I run my code the debugger kicks in when I am trying to assign stuff. I have tried to methods, the first:
MatrixGraph::MatrixGraph(unsigned num_nodes) {
for(int i = 0;i < num_nodes;i++) {
for(int j = 0;j < num_nodes;j++) {
M[i][j] = 0.0;//breaks on this line
}//end i for loop
}//end j for loop
}
and the second method i tried i found on here but that didn't work either:
MatrixGraph::MatrixGraph(unsigned num_nodes) {
for(int i = 0;i < num_nodes;i++) {
M[i].resize(num_nodes);//breaks on this line
}
}
i commented on here where the last line on the call stack is before i get errors. The next line after that on the call stack shows me the class vector and is saying that my Pos is greater than the size of my vector. I assume that this is a size zero matrix, but i don't know why i cant make it bigger. Any suggestions?
Thanks!
The reason your code is failing is that you cant use the [] operation on a vector before that element exists. The usual way to add a value to a vector is to use push_back.
If you want to initialize to 0 you want assign(). Resize the outer vector to the required size and then assign each of the inner vectors with 0
M.resize(num_nodes);
for(int i = 0;i < num_nodes;i++)
{
M[i].assign(num_nodes,0.0f);
}//end i for loop
This can also be done. It is cleaner code but a tad less efficient since it makes 1 extra vector object.
vector<double> temp;
temp.assign(num_nodes,0.0);
M.assign(num_nodes,temp);
or just
M.assign(num_nodes,vector<double>(num_nodes,0.0));
neatest one(courtesy #Mike Seymour) would be
MatrixGraph(unsigned num_nodes)
: M(num_nodes, vector<double>(num_nodes,0.0))
{}
(thanks Mike Seymour for the constructor syntax)
What you are doing here is initializing the outer vector with a temp vector full of 0.0s
You need to populate your vector M with data: M.resize(num_nodes)
This should do it:
MatrixGraph::MatrixGraph(unsigned num_nodes)
{
M.resize(num_nodes);
for(int i = 0;i < num_nodes;i++)
{
M[i].resize(num_nodes);
for(int j = 0;j < num_nodes;j++)
{
M[i][j] = 0.0;
}//end j for loop
}//end i for loop
}

C++ Checking for identical values in 2 arrays

I have 2 arrays called xVal, and yVal.
I'm using these arrays as coords. What I want to do is to make sure that the array doesn't contain 2 identical sets of coords.
Lets say my arrays looks like this:
int xVal[4] = {1,1,3,4};
int yVal[4] = {1,1,5,4};
Here I want to find the match between xVal[0] yVal[0] and xVal[1] yVal[1] as 2 identical sets of coords called 1,1.
I have tried some different things with a forLoop, but I cant make it work as intended.
You can write an explicit loop using an O(n^2) approach (see answer from x77aBs) or you can trade in some memory for performance. For example using std::set
bool unique(std::vector<int>& x, std::vector<int>& y)
{
std::set< std::pair<int, int> > seen;
for (int i=0,n=x.size(); i<n; i++)
{
if (seen.insert(std::make_pair(x[i], y[i])).second == false)
return false;
}
return true;
}
You can do it with two for loops:
int MAX=4; //number of elements in array
for (int i=0; i<MAX; i++)
{
for (int j=i+1; j<MAX; j++)
{
if (xVal[i]==xVal[j] && yVal[i]==yVal[j])
{
//DUPLICATE ELEMENT at xVal[j], yVal[j]. Here you implement what
//you want (maybe just set them to -1, or delete them and move everything
//one position back)
}
}
}
Small explanation: first variable i get value 0. Than you loop j over all possible numbers. That way you compare xVal[0] and yVal[0] with all other values. j starts at i+1 because you don't need to compare values before i (they have already been compared).
Edit - you should consider writing small class that will represent a point, or at least structure, and using std::vector instead of arrays (it's easier to delete an element in the middle). That should make your life easier :)
int identicalValueNum = 0;
int identicalIndices[4]; // 4 is the max. possible number of identical values
for (int i = 0; i < 4; i++)
{
if (xVal[i] == yVal[i])
{
identicalIndices[identicalValueNum++] = i;
}
}
for (int i = 0; i < identicalValueNum; i++)
{
printf(
"The %ith value in both arrays is the same and is: %i.\n",
identicalIndices[i], xVal[i]);
}
For
int xVal[4] = {1,1,3,4};
int yVal[4] = {1,1,5,4};
the output of printf would be:
The 0th value in both arrays is the same and is: 1.
The 1th value in both arrays is the same and is: 1.
The 3th value in both arrays is the same and is: 4.