trouble iterating through multidimensional array - c++

The question is to write a function that returns a bounding rectangle for a set of points in a two dimensional plane. SIZE is two. I know the points will come in this format {double, double} and I know how to create the bounding rectangle. I can't seem to grab the points though. I tried iterating like this.
Rectangle2D getRectangle(const double points[][SIZE], int s) {
for (int i = 0; i < s; i++) {
for (int j = 0; j < SIZE; j++) {
cout << points[s][SIZE] << endl;
}
}
// will put these points in after i figure out the iteration.
Rectangle2D rekt(x, y, width, height);
return rekt;
}

You are accessing the same element element every time, because s and SIZE remain constant. You have to access it like this points[i][j] .
And I'm not sure, but i think you can't pass SIZE within the array argument, you should pass it as an additional parameter.
Good luck ;)

Here you go.
for (int i = 0; i < s; i++) {
for (int j = 0; j < SIZE; j++) {
cout << points[i][j] << endl; //observe i,j
}
}
In above case you are iterating row-wise. If you want to iterate column-wise then following will work.
for (int j = 0; j < SIZE; j++) {
for (int i = 0; i < s; i++) {
cout << points[i][j] << endl; //observe i,j
}
}

Related

2d push_back doesnt save to vector values

I have a 2d vector which should save x and y coordinates. Everything works as intended except saving this values to vector. What did I do wrong?
void Game::GetShips(Board &b)
{
vector<vector<int>> shipCors;
for (int i = 0; i < BOARDSIZE; i++) {
for (int j = 0; j < BOARDSIZE; j++) {
if (b.getSpaceValue(i, j) == SHIP) {
cout << "X :"<< i<<"\n Y:"<<j<<'\n';
shipCors[i].push_back(j);
}
}
}
cout<< shipCors.size()<<'\n';
}
You declared an empty vector
vector<vector<int>> shipCors;
So you may not use the subscript operator
shipCors[i].push_back(j);
You could write
for (int i = 0; i < BOARDSIZE; i++) {
shipCors.resize( shipCors.size() + 1 );
for (int j = 0; j < BOARDSIZE; j++) {
if (b.getSpaceValue(i, j) == SHIP) {
cout << "X :"<< i<<"\n Y:"<<j<<'\n';
shipCors[i].push_back(j);
}
}
}
Pay attention to that as you are using the index i then you need to add a "row" of the vector even if the row will be empty after executing the inner for loop.
It will be even better to resize the vector initially before the for loops like
vector<vector<int>> shipCors;
shipCors.resize( BOARDSIZE );
for (int i = 0; i < BOARDSIZE; i++) {
for (int j = 0; j < BOARDSIZE; j++) {
if (b.getSpaceValue(i, j) == SHIP) {
cout << "X :"<< i<<"\n Y:"<<j<<'\n';
shipCors[i].push_back(j);
}
}
}
An alternative approach is to have a vector declared like
std::vector<std::pair<int, int>> shipCors;
In this case your loop will look like
for (int i = 0; i < BOARDSIZE; i++) {
for (int j = 0; j < BOARDSIZE; j++) {
if (b.getSpaceValue(i, j) == SHIP) {
cout << "X :"<< i<<"\n Y:"<<j<<'\n';
shipCors.emplace_back(i, j);
}
}
}
Or to keep the data sorted you can declare a set like
std::set<std::pair<int, int>> shipCors;

C++ why is there a segmentation fault in my pointer selection sort?

Below is my c++ code. I am trying to implement a selection sort using pointers (start and end). The code compiles, but I am getting a segmentation fault before it will sort the random generated list (currently only prints the random numbers).
Any help as to why this is and how to fix it would be greatly appreciated.
#include<stdio.h>
#include<stdlib.h>
#include <iostream>
using namespace std;
void selectionSort(int *start, int *stop) {
for (int i = *start; i < *stop - 1; ++i) {
int min = i;
for (int j = i + 1; j < *stop; ++j) {
if ((&start[0])[j] < (&start[0])[min])
min = j;
}
swap((&start[0])[i], (&start[0])[min]);
}
}
int main()
{
int size = 10;
int* data = new int[size];
for (int i = 0; i < size; ++i)
{
data[i] = rand() % size;
}
for (int k = 0; k < size; k++)
{
cout << data[k] << " ";
}
cout << endl;
selectionSort(data, data+size);
for (int j = 0; j < size; j++)
{
cout << data[j+1] << " ";
}
return 0;
}
The general logic in your function is in the right direction. However, you seem to be confused between values of the elements of the array and the indexing used to access the elements of the array.
The line
for (int i = *start; i < *stop - 1; ++i)
shows the first signs of the confusion.
You are initializing i with the value of the first element of the array and incrementing the value in the subsequent iterations of the loop. That is not correct. Incrementing the value of the first element of the array does not make logical sense.
*stop causes undefined behavior since stop points to a place one past the last valid element.
You need to use int* i, int* j, and int* min to properly sort the elements. That also means updating almost the entire function accordingly. Here's an updated function that works for me.
void selectionSort(int *start, int *stop) {
for (int* i = start; i < (stop - 1); ++i) {
int* min = i;
for (int* j = i + 1; j < stop; ++j) {
if (*j < *min)
{
min = j;
}
}
swap(*i, *min);
}
}
Also, the following lines in main are not correct. You end up accessing the array using an out of bounds index.
for (int j = 0; j < size; j++)
{
cout << data[j+1] << " ";
}
Replace them by
for (int k = 0; k < size; k++)
{
cout << data[k] << " ";
}

Need advice on 2d arrays

I am currently working on a dungeon crawl game where the user can move throughout a maze on the screen. I decided to use a 2d array for the maze. One problem, I have a function to print the maze although its not working. I want it to print all four of the rows (there are supposed to be 4 0's per row) but it only prints 4 0's in a single line.
int maze[4][4] = {(0,0,0,0),
(0,0,0,0),
(0,0,0,0),
(0,0,0,0)};
for (int i = 0; i < 4; i++)
{
cout <<maze[i][i];
}
You need two loops, one nested inside the other.
One to print the rows.
One to print each column in the current row.
You need nested loop for displaying 2D array.
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
cout<
Try this.
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
cout <<maze[i][j];
}
cout << "\n";
}

Transpose a 2d dynamic matrix

I want to create a transpose function for dynamic 2d arrays. I want the functions to have as parameters the 2d array and the rows and columns. I ve decided to use double pointer. However i m a bit confused about how i gonna call the function from main. So i ve got the above code
#include<iostream>
using namespace std;
void transposeMatrix(double **mat, int rows, int columns)
{
mat = new double*[rows];
for (int i = 0; i < rows; ++i)
{
mat[i] = new double[columns];
}
double temp;
for (int i = 0; i<rows; i++)
{
for (int j = i+1; j<columns; j++)
{
temp=mat[i][j];
mat[i][j]=mat[j][i];
mat[j][i]=temp;
}
}
cout<< "\n";
for (int i = 0; i<rows; i++)
{
for (int j = 0; j<columns; j++)
{
cout << mat[i][j] << " \t";
}
cout << "\n";
}
}
int main()
{
int rows = 10;
int columns = 10;
double mat[rows][columns];
for (int i = 0; i<rows; i++)
{
for (int j = 0; j<columns; j++)
{
mat[i][j] = j;
}
}
for (int i = 0; i<rows; i++)
{
for (int j = 0; j<columns; j++)
{
cout << mat[i][j] << " \t";
}
cout << "\n";
}
//mat = new double[50][1];
transposeMatrix(mat, 10, 10);
system("pause");
return 0;
}
Any idea?
You're very close. You're calling the function correctly and the function's parameter list is correct. First, remove this section from the transpose function:
mat = new double*[rows];
for (int i = 0; i < rows; ++i)
mat[i] = new double[columns];
}
Now make sure all your brackets match up. (There was one missing.)
You can't define a static array (one that looks like this: x[y][z]) with non-constant variables as the size arguments. (I.e. y and z must be constants.) But actually, you're passing a dynamic array to the transpose function anyway, and rows and columns don't have to be constants to do that. So, in main, define a dynamic array like this:
double** mat = new double*[rows];
for (int i = 0; i < rows; i++)
mat[i] = new double[columns];
After that, your code should work. But you could also make it better by putting your matrix display code in a function. Then, instead of cutting and pasting it everywhere, all you have to do is call the function! It's an important habit to get into. Have fun!
There are a couple of major issues with your code.
The biggest one is that a double[10][10] is not convertible to a double** pointer.
You also have a memory leak (mat) in your transposeMatrix() implementation.
I recommend that you separate the concerns of printing a matrix and transposing a matrix. Perhaps a separate methods on a (templated) matrix class.
And now, having said that...
Why write one when a perfectly good implementation already exists?
Example:
#include <boost/numeric/ublas/matrix.hpp>
#include <boost/numeric/ublas/io.hpp>
int main ()
{
using namespace boost::numeric::ublas;
matrix<double> m(3, 3);
for (unsigned i = 0; i < m.size1(); ++i)
{
for (unsigned j = 0; j < m.size2(); ++j)
{
m(i, j) = 3 * i + j;
}
}
std::cout << m << std::endl;
std::cout << trans(m) << std::endl;
}
Output:
[3,3]((0,1,2),(3,4,5),(6,7,8))
[3,3]((0,3,6),(1,4,7),(2,5,8))
double ** transpose(double **matrix, int rows, int columns){
double ** trans;
trans=new double *[columns];
for(int i=0;i<columns;i++){
trans[i]=new double[rows];
for(int j=0;j<rows;j++)
trans[i][j]=matrix[j][i];
}
return trans;
for(int i=0;i<columns;i++)
delete[] trans[i];
delete[] trans;
}
Here is the code for transpose of the matrix.

Array filling mistake

I can't understand what's wrong is in my program. I have such input data:
01000
11110
01000
I want to save it into: vector< vector<int> > matrix;
vector< vector<int> > fillMatrix(vector< vector<int> > matrix, int height, int width, ifstream &read)
{
// Make 2d-array [matrix]
matrix.resize(width);
for (int i=0; i < width; ++i)
matrix[i].resize(height);
// Fill it up with data
for (int i=0; i < height; ++i)
{
std::string tempLine;
std::getline(read, tempLine);
for (int j=0; j < tempLine.length(); ++j)
{
// This shows right information
//std::cout << tempLine[j] << " - " << (int)(tempLine[j] - '0') << "\n";
matrix[i][j] = (int)(tempLine[j] - '0');
}
}
return matrix;
}
matrix = fillMatrix(matrix, 3, 5, ifstreamHandle);
And now, function which shows the matrix:
void showMatrix(vector< vector<int> > matrix, int width, int height)
{
// Show the matrix
for (int i=0; i < height; ++i)
{
for (int j=0; j < width; ++j)
{
std::cout << matrix[i][j];
}
std::cout << "\n";
}
}
showMatrix(matrix, 5, 3);
And the result of showMatrix is:
01000
11100
01000
There are missed '1' in second row. What's wrong?
When you initialise the vector, you have width and height the wrong way around. When you later read from the last two columns, the results will be undefined.
matrix.resize(width);
for (int i=0; i < width; ++i)
matrix[i].resize(height);
should be
matrix.resize(height);
for (int i=0; i < height; ++i)
matrix[i].resize(width);
Your fillMatrix function has width and height in a different order to that in which you call it later in showMatrix. I would advise swapping the order in fillMatrix to keep it the same as in showMatrix.
Be careful filling each row up to tempLine.length, which may be greater than width which will cause an exception. You could also just get the width and height from the vector within showMatrix instead of having these as arguments. And as #Charles says, you should really pass the vector by reference to avoid a copy being made. The vector argument in fillMatrix is currently pretty useless given that you have to return it, unless you turn it into a reference and make the function void.
First of all you are not consistent in your code
for (int i=0; i < width; ++i)
...
for (int i=0; i < height; ++i)
so you are creating matrix like matrix[i].resize(3) for i = 0..4, but write into it using matrix[i][j] where i = 0..2 and j=0..4