initialization of array using vector in cpp - c++

vector< vector<int> > pairSum(vector<int> &arr, int s){
int n = arr.size();
// Used to store result.
vector< vector<int> > ans;
// Checking sum for every element.
for(int i = 0; i < n; i++) {
for(int j = i + 1; j < n; j++) {
if(arr[i] + arr[j] == s) {
vector<int> pair(2);
pair[0] = arr[i];
pair[1] = arr[j];
ans.push_back(pair);
}`enter code here`
}
}
// Used to store final sorted result.
vector<vector<int> > res(ans.size(),vector<int>(2,0));
for(int i = 0; i < ans.size(); i++) {
int a = ans[i][0], b = ans[i][1];
res[i][0] = min(a, b);
res[i][1] = max(a, b);
}
sort(res.begin(),res.end());
return}
what is the need of this line in code
vector<vector<int> > res(ans.size(),vector<int>(2,0));
what is the processing of this line
I think it will intialise new vector of type vector but I want to know on what basis and how the vector is initialised?

Let's break this into parts:
vector<vector<int>> res
Initializes a vector res, of which every element is a vector of integers
(ans.size(), vector<int>(2, 0))
To understand this part it is better to visualize vector<vector<int>> as a 2D array:
+--------------------------------------------+
| |
+---+---+ <----+ |
| 0 | 0 | | |
+---+---+ | |
| 0 | 0 | | |
+---+---+ | |
| 0 | 0 | ans.size() <---------------------------------+
+---+---+ | | |
| 0 | 0 | | | |
+---+---+ | | |
| 0 | 0 | | | |
+---+---+ <----+ | |
|-- 2 --| | |
| | |
+-------------------------------------------+ | |
| | |
vector<vector<int>> res(ans.size(), vector<int>(2, 0)) |
| |
+---------------------------+
So ans.size() is the length of the outer vector, 2 is the length of each of the inner vectors, and 0 is the value to which each element of the inner vectors will be initialized.

Related

Snake game -- tail movement

I'm making a snake game and having trouble with the tail movement. I understand the logic for this part, which is that each segment of the tail follows the previous segment, starting from the end of the tail. I am looking at someone else's code, and it looks like this
#include <iostream>
#include <conio.h>
#include <windows.h>
using namespace std;
bool gameOver;
const int width = 20;
const int height = 20;
int x, y, fruitX, fruitY, score;
int tailx[100], taily[100];
int nTail;
enum eDirecton { Stop, Left, Right, Up, Down } dir;
void Setup()
{
gameOver = false;
dir = Stop;
x = width / 2;
y = height / 2;
fruitX = rand() % width;
fruitY = rand() % height;
score = 0;
}
void Draw()
{
system("cls");
for (int i = 0; i < width + 2; i++)
cout << "#";
cout << endl;
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
if (j == 0)
cout << "#";
if (i == y && j == x)
cout << "O";
else if (i == fruitY && j == fruitX)
cout << "F";
else
{
bool print = false;
for (int k = 0; k < nTail; k++)
{
if (tailx[k] == j && taily[k] == i)
{
cout << "o";
print = true;
}
}
if (!print)
cout << " ";
}
if (j == width - 1)
cout << "#";
}
cout << endl;
}
for (int i = 0; i < width + 2; i++)
cout << "#";
cout << endl;
cout << "Score:" << score << endl;
}
void Input()
{
if (_kbhit())
{
switch (_getch())
{
case 'a':
dir = Left;
break;
case 'd':
dir = Right;
break;
case 'w':
dir = Up;
break;
case 's':
dir = Down;
break;
case 'x':
gameOver = true;
break;
}
}
}
void Logic()
{
for (int i = nTail - 1; i > 0; i--)
{
tailx[i] = tailx[i - 1];
taily[i] = taily[i - 1];
}
tailx[0] = x;
taily[0] = y;
switch (dir)
{
case Left:
x--;
break;
case Right:
x++;
break;
case Up:
y--;
break;
case Down:
y++;
break;
default:
break;
}
if (x >= width) x = 0; else if (x < 0) x = width - 1;
if (y >= height) y = 0; else if (y < 0) y = height - 1;
for (int i = 0; i < nTail; i++)
if (tailx[i] == x && taily[i] == y)
gameOver = true;
if (x == fruitX && y == fruitY)
{
score += 10;
fruitX = rand() % width;
fruitY = rand() % height;
nTail++;
}
}
int main()
{
Setup();
while (!gameOver)
{
Draw();
Input();
Logic();
Sleep(50);
}
return 0;
}
I understand the logic but I don't understand why it works. When we create an array, the value of each element is just a garbage value without initializing each element. So in the code above, when doing
tailx[i] = tailx[i-1];
taily[i] = taily[i-1];
what value is assigned to each element?
When displaying the snake, it has a for loop to go through every coordinate of the screen and inside it has another for loop to compare tailx[i] and taily[i] with each coordinate to find out the right position to print each segment of the tail. Since tailx and tialy are not storing the coordinates of the segments of the tail, how come this code works?
Thank you so much!!
Presumably, you're missing a line at the end that looks something like:
if(nTail < 100) { nTail++; }
Assuming that's the case, nTail is initialized to 0 and that this is all in a loop, the code probably looks something like (I'm using a size of 5 instead of 100 to make visualizing easier)
int tailx[5];
int taily[5];
int nTail = 0; //length
while(true) {
for(int i = nTail -1; i > 0; i--)
{
tailx[i] = tailx[i-1];
taily[i] = taily[i-1];
}
// Let's assume there's some logic here the fetches a new
// x and y. For the sake of debugging, let's assume the
// values will be {(1, 1), (2, 2), (3, 3), (4, 4), (5, 5)}
tailx[0] = x; // x is the x-coordinate of the head
taily[0] = y; //y is the y-coordinate of the head
if(nTail < 5) { nTail++; }
}
Let's step through this!
Before we enter the loop, your tail arrays are going to look like: (I'm using NA here to mean "Garbage")
nTail = 0
+-------------------------+
|Name | 0 | 1 | 2 | 3 | 4 |
|-------------------------|
| X | NA| NA| NA| NA| NA|
+-------------------------+
| Y | NA| NA| NA| NA| NA|
+-------------------------+
We enter the loop, initialize i to nTail - 1 which is -1. This doesn't pass the check of i > 0, so we don't even enter the loop.
We'll now grab new x and y vals and assign them into the tails, along with incrementing nTail. So going into the next loop our variables will look like:
nTail = 1
+-------------------------+
|Name | 0 | 1 | 2 | 3 | 4 |
|-------------------------|
| X | 1 | NA| NA| NA| NA|
+-------------------------+
| Y | 1 | NA| NA| NA| NA|
+-------------------------+
We'll head on in, initialize i to nTail - 1 => 0. This DOESN'T pass the check of i > 0, so again we don't enter the loop (which sounds wrong to me...maybe you're initializing nTail to 1 instead of 0?).
We head on down, grab new x/y vals and increment nTail and restart the loop with:
nTail = 2
+-------------------------+
|Name | 0 | 1 | 2 | 3 | 4 |
|-------------------------|
| X | 2 | NA| NA| NA| NA|
+-------------------------+
| Y | 2 | NA| NA| NA| NA|
+-------------------------+
Initializing i to nTail - 1 => 1 means since i > 0 we'll finally enter the inner loop.
With i = 1, we update our tail arrays:
tailx[1] = tailx[0];
taily[1] = taily[0];
Then head down, grab new values and increment nTail. Our variables now look like:
nTail = 3
+-------------------------+
|Name | 0 | 1 | 2 | 3 | 4 |
|-------------------------|
| X | 3 | 2 | NA| NA| NA|
+-------------------------+
| Y | 3 | 2 | NA| NA| NA|
+-------------------------+
After the next loop, things will look like:
nTail = 4
+-------------------------+
|Name | 0 | 1 | 2 | 3 | 4 |
|-------------------------|
| X | 4 | 3 | 2 | NA| NA|
+-------------------------+
| Y | 4 | 3 | 2 | NA| NA|
+-------------------------+
I'll leave it to you to keep tracing if you so desire.
You're right; this code cannot work, and it has undefined behaviour.
nTail isn't even initialised to anything.
Are you sure it's a full program, and not just snippets glued together? Or a sort of "pseudocode" to show the logic without being actual valid C++? You'd need values for nTail and all the array elements.

Reversing a two-dimentional array in C++

So I am trying to take a 10x10 array with random number inputs and in a certain format, and then display the reversed version of it (position [0][0] will now be [9][9] and so on and so forth, but I'm getting a C6385 error at the part that's supposed to create the reversed array. (problematic part encased in \\)
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
const int ROW = 10;
const int COLUMN = 10;
srand(time(NULL));
int array[ROW][COLUMN] = {};
int transposed[ROW][COLUMN] = {};
for (int i = 0; i < ROW; i++)
{
for (int j = 0; j < COLUMN; j++)
{
array[i][j] = rand() % 10;
}
}
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
for (int i = 0; i < ROW; i++)
{
for (int j = 0; j < COLUMN; j++)
{
int it = ROW - i;
int jt = COLUMN - j;
transposed[i][j] = array[it][jt];
}
}
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
cout << " ORIGINAL" << endl;
for (int i = 0; i < ROW; i++)
{
if (i == 0)
{
cout << " 1 2 3 4 5 6 7 8 8 10" << endl;
cout << " +---+---+---+---+---+---+---+---+---+---+" << endl;
}
for (int j = 0; j < COLUMN; j++)
{
if (((j > 0) && (j < 9)) && (i < 10))
{
cout << " | " << array[i][j];
}
else if (j == 9)
{
cout << " | " << array[i][j] << " |";
}
else if ((j == 0) && (i == 9))
{
cout << i + 1 << " | " << array[i][j];
}
else if ((j == 0) && (i < 9))
{
cout << i+1 << " | " << array[i][j];
}
}
cout << endl;
if (i < 10)
{
cout << " +---+---+---+---+---+---+---+---+---+---+" << endl;
}
}
cout << " Transposed" << endl;
for (int i = 0; i < ROW; i++)
{
if (i == 0)
{
cout << " 1 2 3 4 5 6 7 8 8 10" << endl;
cout << " +---+---+---+---+---+---+---+---+---+---+" << endl;
}
for (int j = 0; j < COLUMN; j++)
{
if (((j > 0) && (j < 9)) && (i < 10))
{
cout << " | " << transposed[i][j];
}
else if (j == 9)
{
cout << " | " << transposed[i][j] << " |";
}
else if ((j == 0) && (i == 9))
{
cout << i + 1 << " | " << transposed[i][j];
}
else if ((j == 0) && (i < 9))
{
cout << i + 1 << " | " << transposed[i][j];
}
}
cout << endl;
if (i < 10)
{
cout << " +---+---+---+---+---+---+---+---+---+---+" << endl;
}
}
return (0);
}
This is problematic:
int it = ROW - i;
int jt = COLUMN - j;
When i is 0, then it is 10. Same for jt Remember [0,0] maps to [9,9] because arrays always start at an index of 0. The last valid element in an N sized array is [N-1], not N.
So when this line is executed:
transposed[i][j] = array[it][jt];
Oops. transposed[0][0] = array[10][10]. That's not what you want.
Hence you want this:
int it = ROW - i - 1;
int jt = COLUMN - j - 1;
Hence, your code runs pretty well at that point:
ORIGINAL
1 2 3 4 5 6 7 8 8 10
+---+---+---+---+---+---+---+---+---+---+
1 | 6 | 6 | 8 | 8 | 6 | 6 | 7 | 9 | 6 | 5 |
+---+---+---+---+---+---+---+---+---+---+
2 | 4 | 2 | 9 | 6 | 0 | 2 | 8 | 9 | 4 | 6 |
+---+---+---+---+---+---+---+---+---+---+
3 | 4 | 8 | 0 | 3 | 0 | 3 | 2 | 5 | 8 | 0 |
+---+---+---+---+---+---+---+---+---+---+
4 | 7 | 0 | 5 | 5 | 3 | 0 | 3 | 5 | 7 | 3 |
+---+---+---+---+---+---+---+---+---+---+
5 | 8 | 3 | 4 | 5 | 4 | 1 | 9 | 7 | 9 | 9 |
+---+---+---+---+---+---+---+---+---+---+
6 | 6 | 7 | 2 | 2 | 3 | 3 | 3 | 8 | 2 | 8 |
+---+---+---+---+---+---+---+---+---+---+
7 | 6 | 2 | 3 | 9 | 6 | 7 | 0 | 5 | 1 | 6 |
+---+---+---+---+---+---+---+---+---+---+
8 | 6 | 9 | 5 | 8 | 0 | 9 | 8 | 9 | 3 | 0 |
+---+---+---+---+---+---+---+---+---+---+
9 | 5 | 5 | 0 | 8 | 3 | 3 | 2 | 6 | 4 | 8 |
+---+---+---+---+---+---+---+---+---+---+
10 | 1 | 1 | 7 | 0 | 2 | 8 | 5 | 2 | 7 | 4 |
+---+---+---+---+---+---+---+---+---+---+
Transposed
1 2 3 4 5 6 7 8 8 10
+---+---+---+---+---+---+---+---+---+---+
1 | 4 | 7 | 2 | 5 | 8 | 2 | 0 | 7 | 1 | 1 |
+---+---+---+---+---+---+---+---+---+---+
2 | 8 | 4 | 6 | 2 | 3 | 3 | 8 | 0 | 5 | 5 |
+---+---+---+---+---+---+---+---+---+---+
3 | 0 | 3 | 9 | 8 | 9 | 0 | 8 | 5 | 9 | 6 |
+---+---+---+---+---+---+---+---+---+---+
4 | 6 | 1 | 5 | 0 | 7 | 6 | 9 | 3 | 2 | 6 |
+---+---+---+---+---+---+---+---+---+---+
5 | 8 | 2 | 8 | 3 | 3 | 3 | 2 | 2 | 7 | 6 |
+---+---+---+---+---+---+---+---+---+---+
6 | 9 | 9 | 7 | 9 | 1 | 4 | 5 | 4 | 3 | 8 |
+---+---+---+---+---+---+---+---+---+---+
7 | 3 | 7 | 5 | 3 | 0 | 3 | 5 | 5 | 0 | 7 |
+---+---+---+---+---+---+---+---+---+---+
8 | 0 | 8 | 5 | 2 | 3 | 0 | 3 | 0 | 8 | 4 |
+---+---+---+---+---+---+---+---+---+---+
9 | 6 | 4 | 9 | 8 | 2 | 0 | 6 | 9 | 2 | 4 |
+---+---+---+---+---+---+---+---+---+---+
10 | 5 | 6 | 9 | 7 | 6 | 6 | 8 | 8 | 6 | 6 |
+---+---+---+---+---+---+---+---+---+---+
It compiled on me without error but there's a problem on values like this
I am using Clion v3.15 and c++ 14
In addition to the answer by #serbie fixing your indexing problem, you can simplify the algorithm for reversing the array itself -- in-place without the need of a second array. With your current algorithm, you are not so much reversing an array as you are simply filling a second array with the elements of the first in reverse order. If you attempted to actually reverse array in-place, you would just end up swapping each element twice and end up with the same array as you started with. Additionally, an odd or even number of rows would provide different results.
For your annotated output, you would still need to output the array with the headings and row-numbers you like, but for the reversal itself, in-place, it can be reduced to, e.g.:
#define ROW 3
#define COL ROW
void rev2d (int (*a)[COL])
{
/* loop rows increment from 0 while row < end row decrementing from ROW-1 */
for (int i = 0, j = ROW-1; i <= j; i++, j--) {
/* loop cols 0->COL-1 and COL-1->0 while i != j or col < endcol */
for (int k = 0, l = COL-1; i != j ? k < COL : k < l; k++, l--) {
/* swap element */
int n = a[i][k];
a[i][k] = a[j][l];
a[j][l] = n;
}
}
}
(note: you can modify the function to take the row and col values if you are not using constants)
The algorithm will work for row and col values greater or equal to 2 (you can add a check for an array of size 1x1 and issue a warning if desired, or just let things remain unchanged as it would be currently).
The handling of odd / even number of rows is done through the ternary used in the inner-loop conditional, e.g. i != j ? k < COL : k < l which reverses full rows unless there are an odd number of rows, and then when i = j it simply reverses to the middle-element
It provides the complete reversal of the array, e.g.:
Example
$ ./bin/revarr2da
original array:
1 2 3
4 5 6
7 8 9
reversed array:
9 8 7
6 5 4
3 2 1
Your algorithm is fine if you want to fill a separate array, if you are interested in swapping the values in place, this is just an additional way to approach it with

Reading triple nested for loop

My code is as follows. My confusion occurs during the 2nd and 3rd loop. Why does the result return 1*** then 12** then 123* then 1234.. I get the j loop is reset to 0 but doesn't it reenter the k loop whenever its true that j<=i?
for(int i = 1; i <= 4; i++)
{
for(int j = 1; j <= i; j++)
cout << j;
for(int k = 4 - i; k >= 1; k--)
cout << "*";
cout << endl;
}
Some clarification first:
Firstly: j is never reset to 0, but to 1.
Secondly: This is imho no triple-nested for-loop, which was be (but is not needed to have your code working as you describe it):
for(...) {
for(...) {
for(...) {
}
}
}
To your confusion:
Pretty printing your code:
for(int i=1; i<=4; i++) {
// Write the digits 1..i (1, 12, 123, 1234)
for(int j=1; j<=i; j++) {
std::cout << j;
}
// Write the stars (***, **, *)
for(int k=(4-i); k>=1; k--) {
std::cout << "*";
}
std::cout << std::endl;
}
Imagine the following sequences:
// Iteration | i | j | k | String
// 1 | 1 | 1 | 3 | 1*
// 2 | 1 | 1 | 2 | 1**
// 3 | 1 | 1 | 1 | 1***\n
// 4 | 2 | 1 | - | 1
// 5 | 2 | 2 | - | 12
// 6 | 2 | 2 | 2 | 12*
// 7 | 2 | 2 | 1 | 12**\n
// 8 | 3 | 1 | - | 1
// 9 | 3 | 2 | - | 12
// 10 | 3 | 3 | - | 123
// 11 | 3 | 3 | 1 | 123*\n
// 12 | 4 | 1 | - | 1
// 13 | 4 | 2 | - | 12
// 14 | 4 | 3 | - | 123
// 15 | 4 | 4 | - | 1234\n
The k-loop is reentered, if the initial index:
// k:=(4-i) >= 1
So entering the k-Loop is exclusively dependent on the index i.
Mathematically:
// (4-i) >= 1
// <=> -i >= (1-3)
// <=> -i >= -3
// <=> i <= 3
So the k-loop is reentered, as long as i is <= 3.
In order to get the effect you want your code should be like this:
for(int i = 1; i <= 4; i++)
{
for(int j = 1; j <= i; j++)
{
cout << j;
for(int k = 4 - i; k >= 1; k--)
cout << "*";
}
cout << endl;
}
if you dont have the {} the k loop is executed only after finishing the j loop

I can't figure out a destructor for this 2D ptr array. Need suggestions

I've been thinking hard for a destructor of 2D pointer array. Any suggestions would be of great help.
The following is the structure of my array where x = int's AND * = pointers
+---+---+---+
| * | * | * |
+-|-+-|-+-|-+
| | V
| | +---+---+---+
| | | x | x | x |
| | +---+---+---+
| V
| +---+---+---+
| | x | x | x |
| +---+---+---+
V
+---+---+---+
| x | x | x |
+---+---+---+
Here is the code for my constructor:
matrix(int x, int y)
{
m = x;
n = y;
p = new(int *[m]);
for(i=0 ; i<m ; i++)
p[i] = new(int[n]);
}
~matrix()
{
for(i=0 ; i<m ; i++)
delete[] p[i];
delete[] p;
}

Dynamic 2D Array Creation Runtime Error

I'm trying to create a multidimentional int array with the following function code:
int ** createIntMatrix(unsigned int rows, unsigned int cols)
{
int ** matrix;
unsigned int i,j;
matrix = (int **) calloc(cols, sizeof(int *));
for(i = 0; i < cols; i++)
matrix[i] = (int *) calloc(rows, sizeof(int));
for(i = 0; i < cols; i++)
for(j = 0; j < rows; j++)
matrix[i][j] = 0;
return matrix;
}
I create three instances using this function in the following code,
cout<<"allocating temporary data holders..."<<endl;
int ** temp_meanR;
int ** temp_meanG;
int ** temp_meanB;
temp_meanR = createIntMatrix(img->height,img->width);
temp_meanG = createIntMatrix(img->height,img->width);
temp_meanB = createIntMatrix(img->height,img->width);
cout<<"....done!"<<endl;
I'm accessing these elements like temp_meanB[4][5].
But unfortunately, I get the following error during runtime:
allocating temporary data holders...
....done!
tp6(1868) malloc: *** error for object 0x122852e08: incorrect checksum for freed object - object was probably modified after being freed.
*** set a breakpoint in malloc_error_break to debug
Abort trap
Where am I going wrong here?
for(i = 0; i < cols; i++)
for(j = 0; i < rows; i++)
matrix[i][j] = 0;
note the inside for loop, it says j=0; i<rows; i++ (before Aarohi Johal's edit)
Next you do not have to set the memory manually to 0, as calloc does it for you.
In C++, you should use new and delete .
In the code segment
matrix = (int **) calloc(cols, sizeof(int *));
for(i = 0; i < cols; i++)
matrix[i] = (int *) calloc(rows, sizeof(int));
I think first the rows should be allocated and then for each row link the int arrays.
Visulize like this:
+--------+
| matrix |
+--------+
| c o l s
| +----------------------------+
V | |
+-- +---+ +---+---+---+ +---+
| | |-->| | | | . . . | |
| +---+ +---+---+---+ +---+
| | |--+
r | +---+ | +---+---+---+ +---+
o | | | +-->| | | | . . . | |
w | +---+ +---+---+---+ +---+
s . .
. .
. .
| | |
| +---+ +---+---+---+ +---+
| | |-->| | | | . . . | |
+-- +---+ +---+---+---+ +---+
First do the rows and then the cols, in the above visualization, then the arr[i][j] interpretation would be like normal array.