I had a question about C++ if anybody can answer it for me, I will really appreciate it.
Say I create an output file and I want to create a 50 x 50 grid in the file. How can I do this without using multidimensional arrays?
I was thinking of this. However, I think the newline character on each line is not considered to be part of the canvas:
//set up 50x50 canvas
for(int i = 1; i <= 50; i++)
{
outfile.put(' ');
for(int j = 1; j <= 50; j++)
outfile.put('\n');
}
//reset pointer to start of file
outfile.seekp(0, ios::beg);
One of the things I wish to accomplish with this grid is to be able to move the pointer around. Any help will be appreciated
You can represent a 2-dimensional array as a 1-dimensional array with the formula row_index * num_columns + column_index. In your case you the number of columns would be 51 instead of 50 to account for the newline.
Related
I'm attempting to learn C++ by creating a small maze generator. To facilitate this, I store a list of Cell(), along with x and y values inside a vector in Maze() (some other pieces of information are included below for completeness, but aren't relevant).
The cells are stored in a vector, with X and Y value of the cells being determined and passed in to each cell as it is created.
The problem I'm having is that each cell appears to have the same x and y values populated.
Here is the relevant code:
vector<Cell*> Maze::cells;
int Maze::width;
int Maze::height;
Maze::Maze(int w, int h)
{
/* Set width and height */
width = w;
height = h;
/* These variables keep track of our position in the maze as we generate it */
int scan_w = 0;
int scan_h = 0;
/* Continue looping until we've visited all cells */
/* Offset by one because the width starts at 1 while the scan is zero-based */
for (int i = 0; i <= (width * height); i++)
{
cells.push_back(new Cell(scan_w,scan_h));
cout << scan_w << "/" << scan_h << endl;
scan_w = (i % w);
if (scan_w == 0)
{
scan_h++;
}
}
for(int i = 0; i <= cells.size(); i++)
{
cout << "[" << cells[i]->x << ", " << cells[i]->y << "] " << &cells[i] << endl;
}
}
Edit: Here is the relevant parts of the Cell class
int Cell::x;
int Cell::y;
Cell::Cell(int location_x, int location_y)
{
x = location_x;
y = location_y;
}
The output of this code (truncated for brevity) is:
Maze maze = Maze(50, 25);
0/0
0/1
1/1
2/1
3/1
4/1
5/1
6/1
7/1
8/1
9/1
...
40/25
41/25
42/25
43/25
44/25
45/25
46/25
47/25
48/25
49/25
[49, 25] 0x632f30
[49, 25] 0x632f38
[49, 25] 0x632f40
[49, 25] 0x632f48
[49, 25] 0x632f50
[49, 25] 0x632f58
[49, 25] 0x632f60
[49, 25] 0x632f68
...
Here are my assumptions:
Based on the output, scan_w and scan_h are being incremented as intended (as if reading a table from left to right, top to bottom).
Based on the flow control documentation/tutorial, my understanding is that the first for loop is properly moving from one element of cells to the next.
Based on the documentation for vector's push_back member, I'm assuming that it is properly inserting the reference to each newly created cell into the vector.
Based on the documentation for the [] operator for vectors, my understanding is that if I access cell[0] and cell[1], I will be accessing different objects (this is confirmed by printing the object's address, as above).
So I'm having trouble understanding why the value of x and y for each cell is 49 and 25, respectively, when any given cell is supposed to be incremented in alignment with scan_w and scan_h.
Lastly, here are a couple of things I considered:
The for loop may be reading the same object (disproved by printing the address of the object).
This may be an issue of scope. I'm used to Python, so my presumption is that scope works the same way, but I'm not well enough versed in C++ to know if that's accurate.
This may have something to do with the way Vectors operate (more or less disproven by the documentation on the [] operator).
The output may be deceptive/the scan_ incrementation code may be buggy. This is the most likely scenario, but I haven't been able to spot anything off yet. Possibly a short break and fresh eyes may reveal something here.
Just a shot in the blue, considering how you have formatted the code for the Cell class. Could it be that x and y are defined static (otherwise you would not write "int Cell:x;" anywhere...)? Then the case is clear, because that is the nature of members defined static. The solution would be to just remove the static keyword.
I see multiple bugs in the shown code.
for (int i = 0; i <= (width * height); i++)
This is iterating one too many times. If, for example, both width and height are 10, this will iterate with i set to the range of 0 to 100 inclusively, or 101 cells, instead of 100.
The next problem is that computation of scan_w and scan_h is unnecessarily complex. This should be a trivial calculation, using simple math, and also fixing the iteration bug at the same time:
for (int i = 0; i < (width * height); i++)
{
int scan_w = i % width;
int scan_h = i / width;
cells.push_back(new Cell(scan_w,scan_h));
}
Another bug is here:
for(int i = 0; i <= cells.size(); i++)
Same problem as the first bug. On the last iteration, i will be equal to cells.size(), and cells[i] will not exist, resulting in undefined behavior.
Again, the iteration should be corrected to:
for(int i = 0; i < cells.size(); i++)
You can start by fixing these problems yourself, then checking to see if the results match your expectations, or if there are still other problems.
hello stack overflowers!
haha I am relatively new to c++ and I have a small problem figuring out small piece of the code. Basically I need to print out a full array of ints in 5 different columns. The thing that throws me off is that I have no clue how many ints are in the array and how many rows it'd create?(it is a 1d array) 2d is very easy to process. I just dont know how to go about this. Any logical help would be much appreciated. I have no problem coding it i just don't know how to set this up. Ive been thinking about it for some time now.
You need to know the total number of elements in the 1d-array and we need decompose the number of these elements in the 1d array on the two multiplier.
First multiplier will be lines, second - rows.
For example if we have 50 elements in the 1d-array
we can assume that we have 10 lines and 5 columns
and then write something like this:
for(int line = 0; line < 10; line++)
{
for( int col = 0; col < 5; col++)
{
cout << setw(5) << arr[line*5 + col];
}
cout << endl;
}
Here's the part of the program I'm having problems with:
// precondition: board is initialized
// postcondition: board is shuffled by randomly swapping 20 values
void shuffle(int board[][NCOLS]) {
int num = rand();
num = num %6 + 1;
for (int i = 0; i < 20; i++) {
}
}
Pretty sure I have it wrong already, I think I may need the rand function but I'm not sure how the for loop would work.
Basically there are 6 pictures and they're in 4 columns, it's a memory game and as of the moment they stay in the same place. I need to make it so that they are random and flipped on the side where you can't see them but I can't figure it out.
I have no idea how to randomize columns especially when they're under the name of simply board and NCOLS.
I can see why this is hard - random_shuffle prefers 1D arrays, and you have a 2D array. Luckily, since arrays are contiguous, that means a 2D array can also be accessed as a 1D array - it's just NCOLS x NROWS elements in memory:
auto begin = &(board[0][0]);
auto end = begin + NCOLS*NROWS;
The MATLAB code samples part of background of an grayscale image by creating a cell array that is backgroundSample{1}, backgroundSample{2}, ... , backgroundSample{9}. Here halfRows and halfCols is the half size of the image.
Since backgroundSample is an array that contains nine 2-D matrices. It confused me that how to write this code in C/C++. Can I get the elements of backgroundSample{i} using something like backgroundSample[i].elements[m][n]?
MATLAB code:
offset = [-60, -20, 20, 60];
for i = 1: 1: 3
for j = 1: 1: 3
backgroundSample{(i - 1) * 3 + j} =
background(halfRows + offset(i): halfRows + offset(i + 1), ...
halfCols + offset(j): halfCols + offset(j + 1));
end;
end;
EDIT:
As we can assign a matrix simply by A = B in MATLAB. For an example, backgroundSample{1} = background(60: 100, 60: 100) in my question and this assignment is in the loops of i: 1→3 and j: 1→3. However, when assigning a matrix in C/C++, it should assign every element one by one. Maybe like this:
for(int i = 0; i < 3; i++)
for(int j = 0; n < 3; j++)
// to get every elements
for(int m = 0 ...)
for(int n = 0 ...)
// not sure whether there is such usage of "->" in array
backgroundSample[(i - 1) * 3 + j]->elements[m][n] = background[i iteration][j iteration]
So there are conflicts between indices of matrix backgroundSample[m][n] and background[i][j]. How to resolve the issue?
The simplest way to implement what you're describing is to declare a multidimensional array:
int backgroundSample[9][3][3];
where the dimensions of each 2-D matrix is assumed to be 3×3. To access the (m, n) element in the k-th matrix, you write backgroundSample[k][m][n], e.g:
for (int m = 0; m < 3; ++m)
{
for(int n = 0; n < 3; ++n)
{
backgroundSample[(i - 1) * 3 + j][m][n] = background[i][j];
}
}
Alternatively, if each sample in this array stores more information, you can declare a structure:
typedef struct
{
int elements[3][3];
// More fields...
} TSample;
and then create an array of these:
TSample backgroundSample[9];
To access an element you would write backgroundSample[k].elements[m][n].
There's also the possibility of allocating the memory dynamically (during runtime, meaning that you don't know how much of these structures you have in advance):
TSample* backgroundSample;
In C++ the actual process of memory allocation would look like this:
backgroundSample = new TSample[9];
Accessing an element would be done by writing backgroundSample[k]->elements[m][n]. Notice the array operator -> which accesses the field elements by dereferencing the pointer backgroundSample[k].
Note: each call to new needs to be accompanied by a matching call to delete when done in order to release the memory, i.e:
delete[] backgroundSample;
Hope that helps!
Let's say that I have a 2D array that looks like:
________________
|10|15|14|20|30|
|14|10|73|71|55|
|73|30|42|84|74|
|14|74|XX|15|10|
----------------
As I showed, the columns don't need to be same size.
Now I need to find the best matching for each column (the one that has most exactly the same items and lowest different). Of course, I could do that in n^2 but it's too slow for me. How can I do it?
I thought about a k-dimension tree and finding the closest neighbor for every one, but I don't know if it's good and it will work as I want (probably not).
Result for example:
First column is most likely third (only three different - 10, 14, 42)
Second column -> fifth (only two different - 15 and 55)
and so on and so on... :)
If you know that all the numbers in the table are 2-digit numbers (i.e. 10 =< x <100), for each column create an array of booleans where you will mark the existing numbers:
bool array[5][100];
std::fill( &array[0][0], &array[0][0] + sizeof(array) , false ); // init to false
for (int i = 0; i < 5; i++)
{
for (int j = 0; j <5; j++)
{
array[i][table[i][j]] = true;
}
}
Should be easy from there.