How to print a grid vector in C++ - c++

I am working on C++ printing vectors in grid.
Here, I need to put random numbers in a vector size of 3x * 3y. And then I have to print them out with two dimensional matrix with one array.
I do not understand how to represent two dimensional matrix with one array.
In addition, I am not sure how to print out multidimensional vectors. I have to work on print_vector function which prints vectors with grid form.
Could you please help me to improve this code below?
int main()
{
populate_vector();
return 0;
}
void populate_vector()
{
int x,y;
cout<<"Enter two Vectors x and y \n->";
cin>> x;
cin>> y;
srand((unsigned)time(NULL));
std::vector<int> xVector((3*x) * (3*y));
for(int i = 0; (i == 3*x && i == 3*y); ++i){
xVector[i] = rand() % 255 + 1;
if(i == 3*x){
cout << "\n";
}
}
print_vector(xVector);
}
void print_vector(vector<int> &x) {
}

I'm not an expert, but I like to just have a vector of vectors.. something like:
void print_vector(vector<vector<int>>& m_vec)
{
for(auto itY: m_vec)
{
for(auto itX: itY)
cout << itX << " ";
cout << endl;
}
}
void populate_vector()
{
int x,y;
cout << "Enter Two Vectors x and y \n ->";
cin >> x;
cin >> y;
srand((unsigned)time(NULL));
vector<vector <int>> yVector;
for(auto i = 0; i < y*3; ++i)
{
vector<int> xVector;
for(auto j = 0; j < x*3; ++j)
xVector.push_back(rand()%255+1);
yVector.push_back(xVector);
}
print_vector(yVector);
}
EDIT: Ooh, I'd never seen this site before, thanks Saykou... here is the code working: http://cpp.sh/3vzg

Something like this will clarify your code, there is a procedure where the vector is populated, and another one where the vector is printed
int main()
{
int x,y;
std::cout<<"Enter two Vectors x and y \n->";
std::cin>> x;
std::cin>> y;
srand((unsigned)time(NULL));
int xSize = x * 3; // it is important to have the size of the final grid stored
int ySize = y * 3; // for code clarity
std::vector<int> xVector( xSize * ySize);
// iterate all y
for ( y = 0 ; y < ySize; ++y) {
// iterate all x
for ( x = 0 ; x < xSize; ++x) {
// using row major order https://en.wikipedia.org/wiki/Row-_and_column-major_order
xVector[y * xSize + x] = rand() % 255 + 1;
}
}
// when printing you want to run y first
for ( y = 0 ; y < ySize; ++y) {
for ( x = 0 ; x < xSize; ++x) {
// iterate all y
printf("%d ", xVector[y * xSize + x] );
}
printf("\n");
}
}
I think you want to pay attention to this step, where you can convert x and y position into a one array dimension. It's simple you just have to multiply the y by the size of x and add x.
So something like this in two dimensions
1 2 3
4 5 6
will end up in something like this
1 2 3 4 5 6
you can see it running here

Related

How do I print out the occurences of each element in an area specified by a bounding box of a 2d matrix?

void searchValidEntries(int arr[101][101], int XL, int YL, int XH, int YH){
int sizeX = (XL - XH) + 1;
int sizeY = (YH - YL) + 1;
for (int i = XH; i < XH + sizeX; i++ ){
for (int j = YL; j < YL + sizeY; j++){
cout << arr[i][j] << ' ';
}
}
}
In the above code, I'm looping through a bounding box in a 2d array.
The coordinates of the array to be assigned a bounding box and the array itself are included as parameters in a function : int arr[101][101], int XL, int YL, int XH, int YH
The commented code cout << arr[i][j] << ' '; prints out the elements in the designated bounding box and I've run it so I know it actually prints out.
However, I want to get the frequency of each element in the bounding box, with the exception of 0, to be printed out.
I'm assuming that the required code will go in the for loop but I have no idea to start as I'm now learning all the semantics of C++.
I'm expecting an output of something like:
5 --> 3
83 --> 2
23 --> 9
There are multiple ways to do this. I suggest using a vector< pair< int, int >>.
Each element of this vector holds two things:
1- a value that has been visited
2- the occurrence of this value
I've added some comments to my code to clarify this method.
#include <iostream>
using namespace std;
#include <vector>
void searchValidEntries(int arr[101][101], int XL, int YL, int XH, int YH) {
vector<pair<int, int>> holder_vec;
int sizeX = (XL - XH) + 1;
int sizeY = (YH - YL) + 1;
for (int i = XH; i < XH + sizeX; i++) {
for (int j = YL; j < YL + sizeY; j++) {
bool thisElementIsNew = true; // By default, it's the first occurence of this element.
for (auto& it : holder_vec) { // Iterate the vector of previously considered elements and chekc this target value.
if (it.first == arr[i][j]) {
it.second++; // Increase the occurence of this element by one.
thisElementIsNew = false; // This value has been previously visited.
break; // Stop iterating vector
}
}
if (thisElementIsNew) { // Add a new pair to holder_vec;
const pair<int, int> newPair(arr[i][j], 1); // newPair.first = The value of this element. // newPair.second = the occurence of this value.
holder_vec.push_back(newPair);
}
}
}
// Print result:
for (const auto& it : holder_vec) {
cout << it.first << " ---> " << it.second << endl;
}
}

Create a recursive for statement in c++

I'd like to know if it is actually possible to create / define an homemade for statement in C++. Something similar already have been asked here:
"How to create a for loop like command in C++? #user9282's answer"
What I ask for is if we can make a for that performs as much for as we want (n times).
As example, here is a basic for-loop statement :
for (int i = 0; i < 10; i++) { ... }
I'm wondering if the new for-loop could result more like this :
int x = 20; // individual loops
int y = 3; // = amount of for-loops performed (in this case, 3)
// maybe some code generating for-loops here or something...
// result:
for (int i = 0; i < x; i++)
{
for (int j = 0; j < x; j++)
{
for (int k = 0; k < x; k++)
{
// if "y" was equal to 5, there would be 2 more for-loops here
instructions; // we can use "i", "j", "k", ... here
}
}
}
Do you think this could be possible in c++ ?
[EDIT: made clearer the code above]
In one sentence: I want to create a statement (e.g. if, while, for, switch) that puts for-loops into for-loops (just like the code above has for-loops into for-loops) so we can access multiple increments (i, j, k, ...) in the same scope.
You can easily do that with recursive functions that contains a for loop. I would do it like this:
void foo() {
for (...) {
foo();
}
}
That way, you can do as many nested for loops as you want.
However, if you want define a recursive nested for loops in your code without defining an external function, you could use lambdas:
auto recursive = [](auto func) {
// This is needed to make a recursive lambda
return [=](auto... args){
func(func, args...);
};
};
auto nestedForLoop = recursive([](auto self){
// Here's your recursive loop!
for (...) {
self();
}
});
// You can simply call `nestedForLoop` to execute loop
nestedForLoop();
If you have n nested for loops with the same bound x, you are performing xn iterations. In that case, you can just use a single index and convert it into multiple indices for convenience. For n = 2, for example:
for (int z = 0; z < x * x; ++z) {
const int i = z / x;
const int j = z % x;
// ...
}
For n = 3:
for (int z = 0; z < x * x * x; ++z) {
// The last "% x" in this line is for illustration only.
const int i = (z / x / x) % x;
const int j = (z / x) % x;
const int k = z % x;
// ...
}
i, j, k, etc. are the digits of the current iteration number z converted to base x. You could generalise this into a recursive function, or one that unpacks the digits into a vector.
Quick answer:
#include <iostream>
using namespace std;
void recursive(int x, int y, int tempY) // 2d recursive for loop
{
if (x > 0)
{
if (y > 0)
{
cout << x << " " << y << " \n ";
recursive(x, y - 1, tempY);
}
else
{
y = tempY;
recursive(x - 1, y, tempY);
}
}
}
void recursive(int x, int y, int z, int tempY, int tempZ) // 3d recursive for loop
{
if (x > 0)
{
if (y > 0)
{
if (z > 0)
{
cout << x << " " << y << " " << z << " \n ";
recursive(x, y, z - 1, tempY, tempZ);
}
else
{
z = tempZ;
recursive(x, y - 1, z, tempY, tempZ);
}
}
else
{
y = tempY;
recursive(x - 1, y, z, tempY, tempZ);
}
}
}
int main()
{
recursive(1, 2, 2); // x = 1, y = 2
recursive(1, 2, 3, 2, 3); // x = 1, y = 2, z = 3
}
Quick answer:
void n_for_loop(int x, int size, int arr[])
{
static int* arrTemp(new int[size]);
if (x >= size)
{
for (int i = 0; i < size; i++)
{
cout << arrTemp[i] << " ";
}
cout << endl;
return;
}
for (int i = 0; i < arr[x]; i++)
{
arrTemp[x] = i;
n_for_loop(x + 1, size, arr);
}
}

filling my array with random values C++

I'm trying to make a simple battle ship game. I'm stuck on trying to randomly place the ships on my board.I have a feeling it is because I should be using a vector instead of an array. but I'm not sure how to create a 2d vector.
Here's what I have so far:
using namespace std;
void clearBoard(const int row, const int col)
{
int grid[row][col];
for (int i = 0; i < row; i++) {
for (int j = 0; j < col;j++) {
grid[i][j] = 0;
cout << grid[i][j] << " ";
}
cout << endl;
}
}
void setShips(int max_ships1, int row, int col)
{
int ship_counter = 0;
while(ship_counter < max_ships1) {
int x = rand() % row;
int y = rand() % col;
int matrix[x][y]
if (matrix[x][y] != 1) {
ship_counter++;
matrix[x][y] = 1;
cout << matrix[x][y] << " ";
}
cout << endl;
}
}
int main(int argc, char* argv[])
{
int _row = atoi(argv[0]);
int _col = atoi(argv[2]);
int max_ships;
if (_row > _col) {
max_ships = _row;
}
else if (_col > _row) {
max_ships = _col;
}
else {
max_ships = _row;
}
cout << "enter the size of the board:";
cin >> _row >> _col;
clearBoard(_row, _col);
setShips(_row,_col,max_ships);
return 0;
}
If the user decides on a 3x3 board, the first function returns:
0 0 0
0 0 0
0 0 0
I'm hoping to randomly generate 1's to represent a battleship's position.
Here's an example on a 3x3 board:
1 0 0
0 1 0
1 0 0
Thanks.
Your main problem is that grid goes out of scope (and is effectively deleted) when clearBoard returns, and matrix (a completely unrelated array to grid) goes out of scope each time through your while loop. That means that you're filling grid with zeroes, then creating a bunch of other arrays with random data and sometimes setting one element to 1. You need to either make grid global, or return it from clearBoard and pass it to setShips as an argument.
Passing around multidimensional raw arrays is kind of complicated, so using a vector might make this a bit easier for you if you don't want to make the array global. To create a two-dimensional vector, you might think that std::vector<std::vector<int>> will work, but that's not quite right. You can do it that way, as mentioned in the comments, but technically, std::vector<std::vector<int>> is what's called a jagged array, meaning that you can have each row be a different length - unlike your raw 2D array, where you know that each row must always be the same length.
The proper way to make a two-dimensional array with a vector is this:
std::vector<int> grid(row * col);
grid[i * row + j] = 1; // Or i * col + j will also work.
As you can see, it's a bit more complicated to get an element out by its (x,y) coordinates. It doesn't matter which of the two calculation methods you use, but in one version i is x and j is y, while in the other, the reverse is true (i is y, etc).
You can also set up a 2D vector like this :
#include<vector>
#include<iostream>
using namespace std;
int main()
{
std::vector< std::vector<int> > grid2D;
//m * n is the size of the grid
int m = 10;
int n = 10;
//Grow rows by m
grid2D.resize(m);
//Grow Columns by n
for(int i = 0 ; i < m ; ++i) grid2D[i].resize(n);
// print out 2D grid on screen
for(i = 0 ; i < m ; ++i){
for(int j = 0 ; j < n ; ++j){
grid2D[i][j]=0;
cout<<""<<grid2D[i][j]<<" ";
}
cout<<"\n";
}
cout<<"\n";
return 0;
}

Trying to create a matrix plot, but something is wrong

Now, the main goal of the program is to create a 121x61 matrix, reset it, and draw two lines which represent the plot plane. However, this program for some reason does create the plot for the y line, but it somehow copies it a few positions in the matrix, again (It skips one value though). The plot has to be drawn by replacing the 0s with 1s.
Here's the code:
#include <iostream>
#include <cmath>
#define rd 57.2957795
#define k 0.05
using namespace std;
void rmat(int matrix[121][61])
{
for (int i=0;i<121;i++)
{
for(int j=0;j<61;j++)
{
matrix[i][j] = 0;
}
}
}
void matrix_print(int matrix[121][61])
{
for( int y = 0; y < 61 ; y++ )
{
for( int x = 0; x < 121; x++ )
{
cout << matrix[y][x];
}
cout << "\n";
}
}
void mplot(int matrix[121][61])
{
for( int y = 0; y < 61 ; y++ )
matrix[y][0] = 1;
}
int main(void)
{
int matrix[121][61];
int i,x=0;
double y = 0;
double temp;
rmat(matrix);
system("mode con: cols=200 lines=200");
/* for( x ; x < 180 ; x = x + 4 )
{
temp = cos(double(x) / rd);
}
*/
mplot(matrix);
matrix_print(matrix);
system("pause");
}
You have your matrix indices the wrong way round in several places: the first index runs from 0 to 120 and the second runs from 0 to 60, not the other way around.
Here is an example of one such mistake:
for( int y = 0; y < 61 ; y++ )
{
for( int x = 0; x < 121; x++ )
{
cout << matrix[y][x];

Sorting an array diagonally

I've looked up some websites but I couldn't find an answer to my problem.
Here's my code:
#include "stdafx.h"
#include <iostream>
#include <math.h>
#include <time.h>
#include<iomanip>
#include<array>
#include <algorithm>
using namespace std;
const int AS = 6;
int filling(void);
void printing(int[AS][AS]);
int forsorting(int[][AS], int);
int main()
{
int funny = 0;
int timpa = 0;
int counter = 0;
int Array[AS][AS];
srand(time(0));
for (int i = 0; i<AS; i++)
{
for (int j = 0; j<AS; j++)
Array[i][j] = filling();
}
cout << "The unsorted array is" << endl << endl;
printing(Array);
cout << "The sorted array is" << endl << endl;
for (int il = 0; il<AS; il++)
{
for (int elle = 0; elle<AS; elle++)
Array[il][elle] =forsorting(Array, funny);
printing(Array);
}
system("PAUSE");
return 0;
}
int filling(void)
{
int kira;
kira = rand() % 87 + 12;
return kira;
}
void printing(int Array[AS][AS])
{
int counter = 0;
for (int i = 0; i<AS; i++)
{
for (int j = 0; j<AS; j++)
{
cout << setw(5) << Array[i][j];
counter++;
if (counter%AS == 0)
cout << endl << endl;
}
}
}
int forsorting(int Array[AS][AS], int funny)
{
int c, tmp, x;
int dice = 0;
int Brray[AS*AS];
int timpa = 0;
int super = 0;
//Transofrming Array[][] into Brray[]
for (int i = 0; i < AS; i++)
{
for (int k = 0; k < AS; k++)
{
Brray[timpa] = Array[i][k];
timpa++;
}
}
//Bubble sorting in Brray[]
for (int passer = 1; passer <= AS-1; passer++)
{
for (int timon = 1; timon <= AS-1; timon++)
{
if (Brray[timpa]>Brray[timpa + 1])
{
super = Brray[timpa];
Brray[timpa] = Brray[timpa + 1];
Brray[timpa + 1] = super;
}
}
}
//Transforming Brray[] into Array[][]
for (int e = 0; e<AS; e++)
{
for (int d = 0; d<AS; d++)
{
Brray[dice] = Array[e][d];
dice++;
}
}
***There's a part missing here***
}
What I have to do is, write a program using 3 functions.
The 1st function would fill my 2D array randomly (no problem with this part)
the 2nd function would print the unsorted array on the screen (no problem with this part)
and the 3rd function would sort my array diagonally as shown in this picture:
Then I need to call the 2nd function to print the sorted array. My problem is with the 3rd function I turned my 2D array into a 1D array and sorted it using Bubble sorting, but what I can't do is turn it back into a 2D array diagonaly sorted.
If you can convert from a 2D array to a 1D array, then converting back is the reverse process. Take the same loop and change around the assignment.
However in your case the conversion itself is wrong. It should take indexes in the order (0;0), (0;1), (1;0). But what it does is take indexes in the order (0;0), (0;1), (1;1).
My suggestion is to use the fact that the sum of the X and Y coordinates on each diagonal is the same and it goes from 0 to AS*2-2.
Then with another loop you can check for all possible valid x/y combinations. Something like this:
for ( int sum = 0; sum < AS*2-1; sum++ )
{
for ( int y = sum >= AS ? sum-AS+1 : 0; y < AS; y++ )
{
x = sum - y;
// Here assign either from Array to Brray or from Brray to Array
}
}
P.S. If you want to be really clever, I'm pretty sure that you can make a mathematical (non-iterative) function that converts from the index in Brray to an index-pair in Array, and vice-versa. Then you can apply the bubble-sort in place. But that's a bit more tricky than I'm willing to figure out right now. You might get extra credit for that though.
P.P.S. Realization next morning: you can use this approach to implement the bubble sort directly in the 2D array. No need for copying. Think of it this way: If you know a pair of (x;y) coordinates, you can easily figure out the next (x;y) coordinate on the list. So you can move forwards through the array from any point. That is all the the bubble sort needs anyway.
Suppose you have a 0-based 1-dimensional array A of n = m^2 elements. I'm going to tell you how to get an index into A, given and a pair of indices into a 2D array, according to your diagonalization method. I'll call i the (0-based) index in A, and x and y the (0-based) indices in the 2D array.
First, let's suppose we know x and y. All of the entries in the diagonal containing (x,y) have the same sum of their coordinates. Let sum = x + y. Before you got to the diagonal containing this entry, you iterated through sum earlier diagonals (check that this is right, due to zero-based indexing). The diagonal having sum k has a total of k + 1 entries. So, before getting to this diagonal, you iterated through 1 + 2 + ... + (sum - 1) entries. There is a formula for a sum of the form 1 + 2 + ... + N, namely N * (N + 1) / 2. So, before getting to this diagonal, you iterated through (sum - 1) * sum / 2 entries.
Now, before getting to the entry at (x,y), you went through a few entries in this very diagonal, didn't you? How many? Why, it's exactly y! You start at the top entry and go down one at a time. So, the entry at (x,y) is the ((sum - 1) * sum / 2 + y + 1)th entry, but the array is zero-based too, so we need to subtract one. So, we get the formula:
i = (sum - 1) * sum / 2 + y = (x + y - 1) * (x + y) / 2 + y
To go backward, we want to start with i, and figure out the (x,y) pair in the 2D array where the element A[i] goes. Because we are solving for two variables (x and y) starting with one (just i) and a constraint, it is trickier to write down a closed formula. In fact I'm not convinced that a closed form is possible, and certainly not without some floors, etc. I began trying to find one and gave up! Good luck!
It's probably correct and easier to just generate the (x,y) pairs iteratively as you increment i, keeping in mind that the sums of coordinate pairs are constant within one of your diagonals.
Store the "diagonally sorted" numbers into an array and use this to display your sorted array. For ease, assume 0-based indexing:
char order[] = { 0, 1, 3, 6, 10, 2, 4, 7, 11, 15, .. (etc)
Then loop over this array and display as
printf ("%d", Array[order[x]]);
Note that it is easier if your sorted Array is still one-dimensional at this step. You'd add the second dimension only when printing.
Following may help you:
#include <algorithm>
#include <iomanip>
#include <iostream>
#include <vector>
template<typename T>
class DiagArray
{
public:
DiagArray(int size) : width(size), data(size * size), orders(size * size)
{
buildTableOrder(size);
}
const T& operator() (int x, int y) const { return data[orders[width * y + x]]; }
T& operator() (int x, int y) { return data[orders[width * y + x]]; }
void sort() { std::sort(data.begin(), data.end()); }
void display() const {
int counter = 0;
for (auto index : orders) {
std::cout << std::setw(5) << data[index];
counter++;
if (counter % width == 0) {
std::cout << std::endl;
}
}
}
private:
void buildTableOrder(int size)
{
int diag = 0;
int x = 0;
int y = 0;
for (int i = 0; i != size * size; ++i) {
orders[y * size + x] = i;
++y;
--x;
if (x < 0 || y >= size) {
++diag;
x = std::min(diag, size - 1);
y = diag - x;
}
}
}
private:
int width;
std::vector<T> data;
std::vector<int> orders;
};
int main(int argc, char *argv[])
{
const int size = 5;
DiagArray<int> da(size);
for (int y = 0; y != size; ++y) {
for (int x = 0; x != size; ++x) {
da(x, y) = size * y + x;
}
}
da.display();
std::cout << std::endl;
da.sort();
da.display();
return 0;
}
Thank you for your assistance everyone, what you said was very useful to me. I actually was able to think about clearly and came up with a way to start filling the array based on your recommendation, but one problem now, Im pretty sure that my logic is 99% right but there's a flaw somewhere. After I run my code the 2nd array isnt printed on the screen. Any help with this?
#include "stdafx.h"
#include <iostream>
#include <math.h>
#include <time.h>
#include<iomanip>
#include<array>
#include <algorithm>
using namespace std;
const int AS = 5;
int filling(void);
void printing(int[AS][AS]);
int forsorting(int[][AS], int);
int main()
{
int funny = 0;
int timpa = 0;
int counter = 0;
int Array[AS][AS];
srand(time(0));
for (int i = 0; i<AS; i++)
{
for (int j = 0; j<AS; j++)
Array[i][j] = filling();
}
cout << "The unsorted array is" << endl << endl;
printing(Array);
cout << "The sorted array is" << endl << endl;
for (int il = 0; il<AS; il++)
{
for (int elle = 0; elle<AS; elle++)
Array[il][elle] =forsorting(Array, funny);
}
printing(Array);
system("PAUSE");
return 0;
}
int filling(void)
{
int kira;
kira = rand() % 87 + 12;
return kira;
}
void printing(int Array[AS][AS])
{
int counter = 0;
for (int i = 0; i<AS; i++)
{
for (int j = 0; j<AS; j++)
{
cout << setw(5) << Array[i][j];
counter++;
if (counter%AS == 0)
cout << endl << endl;
}
}
}
int forsorting(int Array[AS][AS], int funny)
{int n;
int real;
int dice = 0;
int Brray[AS*AS];
int timpa = 0;
int super = 0;
int median;
int row=0;
int col=AS-1;
//Transofrming Array[][] into Brray[]
for (int i = 0; i < AS; i++)
{
for (int k = 0; k < AS; k++)
{
Brray[timpa] = Array[i][k];
timpa++;
}
}
//Bubble sorting in Brray[]
for (int passer = 1; passer <= AS-1; passer++)
{
for (int timon = 1; timon <= AS-1; timon++)
{
if (Brray[timpa]>Brray[timpa + 1])
{
super = Brray[timpa];
Brray[timpa] = Brray[timpa + 1];
Brray[timpa + 1] = super;
}
}
}
//Transforming Brray[] into sorted Array[][]
for(int e=4;e>=0;e--)//e is the index of the diagonal we're working in
{
if(AS%2==0)
{median=0.5*(Brray[AS*AS/2]+Brray[AS*AS/2-1]);
//We start filling at median - Brray[AS*AS/2-1]
while(row<5 && col>=0)
{real=median-Brray[AS*AS/2-1];
Array[row][col]=Brray[real];
real++;
col--;
row++;}
}
else {
median=Brray[AS*AS/2];
//We start filling at Brray[AS*AS/2-AS/2]
while(row<5 && col>=0)
{real=Brray[AS*AS/2-AS/2];
n=Array[row][col]=Brray[real];
real++;
col--;
row++;}
}
}
return n;
}
Thanks again for your assistance