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;
Related
I am trying to copy a matrix from an old matrix class to an armadillo matrix. Unfortunately when attempting to do this with a for loop the armadillo matrix will copy the value from the old matrix to the ENTIRE column when the lowest-most element is non-zero (I am using sparse matrices). I have attached the code that is being used below. This is very simplified because I need to figure out why it is doing this first. According to the documentation this should work.
main()
{
OldMatrixClass MatrixA(size, size);
FillMatrix(MatrixA, size);
for (auto i = 0; i < size; i++)
{
for (auto j = 0; j < size; j++)
{
file << MatrixA[i][j] << "\t";
}
file << "\n";
}
arma::Mat<double> ArmaA(size, size);
ArmaA.zeros();
CopyMatrix(MatrixA, ArmaA, size);
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size; j++)
{
file << ArmaA[i,j] << "\t";
}
file << "\n";
}
}
void FillMatrix(OldMatrixClass &A, int size)
{
double num = 0.15;
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size; j++)
{
if (rand() % 101 < 26)
{
A[i][j] = num;
}
else
{
A[i][j] = 0;
}
}
}
}
void CopyMatrix(OldMatrixClass A, arma::Mat<double> &B, int size)
{
for (int k = 0; k < size; k++)
{
for (int j = 0; j < size; j++)
{
B[j, k] = A[j][k];
}
}
}
This is the output when I run this code... As you can see only the entire columns are altered if the last element in MatrixA column is non-zero.
Output
Is there something I'm doing wrong? Is my syntax messed up somewhere?
See the documentation:
Caveat: accessing elements via [i,j] and [i,j,k] does not work correctly in C++; instead use (i,j) and (i,j,k)
Please help me as I am new to programming and I have made this program and it looks fine to me but I am getting garbage values instead of sum of two matrix.I have applied the concept of operator overloading to find the sum of two matrices but I am getting garbage values again and again?Please help me that where is the problem?Thanks.Any help is completely appreciated
#include<iostream>
#include<string>
using namespace std;
class Matrix {
private:
int matrix[2][2];
public:
Matrix operator + (Matrix Sum)
{
Matrix sum[2][2];
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 2; j++)
{
sum[i][j].matrix[i][j] = matrix[i][j] + Sum.matrix[i][j];
return(sum[i][j]);
}
}
}
void setMatrix(int m[][2])
{
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 2; j++)
{
matrix[i][j] = m[i][j];
}
}
}
void Display()
{
cout << "\n\nThe matrix finally equals: ";
for (int i = 0; i < 2; i++)
{
cout << " ";
for (int j = 0; j < 2; j++)
{
cout<<matrix[i][j];
if (j == 2 - 1)
cout << endl;
}
}
}
};
int main()
{
Matrix m1, m2,sum;
const int size=2;
int matrix1[size][size];
int matrix2[size][size];
cout << "Enter the values of matrix 1 (2 X 2)\n\n";
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size; j++)
{
cin >> matrix1[i][j];
}
}
cout << "Enter the values of matrix 2 (2 X 2)\n\n";
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size; j++)
{
cin >> matrix2[i][j];
}
}
cout <<"\n\nSetting the values now\n\n";
m1.setMatrix(matrix1);
m2.setMatrix(matrix2);
sum = m1 + m2;
cout << "\n\nMatrix 1 (2 X 2) is : ";
for (int i = 0; i < size; ++i)
{
for (int j = 0; j < size; ++j)
{
cout << matrix1[i][j] << " ";
if (j == size - 1)
cout << endl;
}
}
cout << "\n\nMatrix 2 (2 X 2) is : ";
for (int i = 0; i < size; ++i)
{
for (int j = 0; j < size; ++j)
{
cout << matrix2[i][j] << " ";
if (j == size - 1)
cout << endl;
}
}
cout << "\n\nSum of two matrices is equal to (2 X 2) is : ";
sum.Display();
return 0;
}
Let's take a close look at you operator+, there are two major errors:
Matrix sum[2][2]; is an array of matrices, but you want to return only a single Matrix, not multiple. Also the name is bad, because you already have a parameter with a similiar name. And yes, C++ is case sensitive, but such similiar names are problematic for human readers ;).
Look where the return is. It will return during the first iteration, e.g.
sum[i][j].matrix[i][j] = matrix[i][j] + Sum.matrix[i][j];
will be called just once, with i and j being zero. Thus it sets only one entry and returns immediately afterwards (leaving the other 3 values uninitialized). That's where the garbage values come from, technically it's undefined behaviour.
Here is what the function should look like, but please don't just copy-paste, but take some time to understand it.
Matrix operator + (Matrix rhs) // One of the two names needed to change.
{
Matrix sum; //only one value with a proper name
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 2; j++)
{
// better be explicit and use this, imo
sum.matrix[i][j] = this->matrix[i][j] + rhs.matrix[i][j];
}
}
return sum; // return only after all the calculations.
}
So, I'm trying to swap the matrix elements with respect to the main diagonal. I have tried using temp method (switching values while using temp variable), also tried std::swap(a,b). Somehow it only swaps upper right side of the matrix and leaves another half not changed.
How do I make everything swap?
My code:
#include <iostream>
using namespace std;
int main()
{
const int n = 7;
srand (time(NULL));
int matrix[n][n];
cout << "Original Matrix :" << endl;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
(i == j) ? matrix[i][j] = 0 : matrix[i][j] = rand() % 100+1;
cout << matrix[i][j] << "\t";
}
cout << endl;
}
cout << "\nRemade Matrix:" << endl;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
int temp = matrix[i][j];
matrix[i][j] = matrix[j][i];
matrix[j][i] = temp;
// swap(matrix[i][j], matrix[j][i]); //another method
cout << matrix[i][j] << "\t";
}
cout << endl;
}
return 0;
}
You are basically swapping them twice, replace your swapping loops with this. Notice the condition of the second loop, it's j < i. Then, you can print it with another set of loops.
for (int i = 0; i < n; i++)
for (int j = 0; j < i ; j++)
swap(matrix[i][j], matrix[j][i]);
Your logic is almost ok. Just the inner loop counter will start from "i+1" else after the swapping the value is again getting overlapped. Try the following code and make sure you understand it. Happy coding!
for (int i = 0; i < n; i++)
{
for (int j = i + 1; j < n; j++)
{
int temp = matrix[i][j];
matrix[i][j] = matrix[j][i];
matrix[j][i] = temp;
}
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
cout << matrix[i][j] << "\t";
}
cout << endl;
}
I am trying to create a 2d vector of set size and then insert data into it. The issue I am having is being able to insert the data filling up each column and row in the 2d vector.
I have read through various other threads, but cannot find an implementation that works for me.
Here is some sample code for my issue:
int main()
{
vector<string> strVec = { "a","b","c","d" };
// letters to insert into vector
// this is just a sample case
vector< vector<string>> vec; // 2d vector
int cols = 2; // number of columns
int rows = 2; // number of rows
for (int j = 0; j < cols; j++) // inner vec
{
vector<string>temp; // create a temporary vec
for (int o = 0; o < rows; o++) // outer vec
{
temp.push_back("x"); // insert temporary value
}
vec.push_back(temp); // push back temp vec into 2d vec
}
// change each value in the 2d vector to one
// in the vector of strings
// (this doesn't work)
// it only changes the values to the last value of the
// vector of strings
for (auto &v : strVec)
{
for (int i = 0; i < vec.size(); i++)
{
for (int j = 0; j < vec[i].size(); j++)
{
vec[i][j] = v;
}
}
}
// print 2d vec
for (int i = 0; i < vec.size(); i++)
{
for (int j = 0; j < vec[i].size(); j++)
{
cout << vec[i][j];
}
cout << endl;
}
}
You are assigning same string to all elements of vec again and again in the loop for (auto &v : strVec).
That is, vec[0][0]=vec[0][1]=vec[1][0]=vec[1][1]=a, vec[0][0]=vec[0][1]=vec[1][0]=vec[1][1]=b, and so on.
Removing this outer loop and assigning strVec[i*cols+j] to vec[i][j], we can get desired output.
DEMO is here.
for (int i = 0; i < vec.size(); i++)
{
for (int j = 0; j < vec[i].size(); j++)
{
vec[i][j] = strVec[i*cols+j];
}
}
for (int i = 0; i < vec.size(); i++)
{
for (int j = 0; j < 2; j++)
{
cout << vec[i][j];
}
cout << endl;
}
Following is my code:
void matrix(int rowsInA, int columnsInA, int columnsInB){
std::vector< vector<int> > a;
std::vector< vector<int> > b;
for (int i = 0; i < rowsInA; i++) {
vector<int> myRow(1);
a.push_back(myRow);
for (int j = 0; j < columnsInA-1; j++) {
int x = rand() % 100;;
myRow.push_back(x);
}
}
for (int i = 0; i < rowsInA; i++) {
vector<int> myRow(1);
b.push_back(myRow);
for (int j = 0; j < columnsInB-1; j++) {
int x = rand() % 100;;
myRow.push_back(x);
}
}
std::vector< vector<int> > c = multiply(a, b);
for (int i = 0; i < rowsInA; i++) {
for (int j = 0; j < columnsInB; j++) {
cout << c[i][j];
}
}
}
std::vector< vector<int> > multiply(std::vector< vector<int> > a , std::vector< vector<int> > b) {
int rowsInA = 9;
int columnsInA = 9; // same as rows in B
int columnsInB = 9;
std::vector< vector<int> > d;
for (int i = 0; i < rowsInA; i++) {
for (int j = 0; j < columnsInB; j++) {
vector<int> myRow;
myRow.push_back(a[i][0]);
d.push_back(myRow);
for (int k = 0; k < columnsInA; k++) {
myRow.push_back(myRow[i]+ a[i][k] * b[k][j]);//error here
}
}
}
return d;
}
first function matrix() creates two vector within a vector and assigns random values to it and then call multiply in which vectors are multiplied.
It is giving vector subscript out of range error
Your code:
for (int i = 0; i < rowsInA; i++) {
vector<int> myRow(1);
a.push_back(myRow);
for (int j = 0; j < columnsInA-1; j++) {
int x = rand() % 100;;
myRow.push_back(x);
}
}
Constructs a single element vector, pushes it on to a, appends some
values to your temporary, and then throws it away. C++ is not Java or C#. The vector at the back of a is not changed by changes to myRow.
You also seem to be putting a fixed value as the first element of myRow, and
then appending randomness to it. Is that what you meant?
What you need is:
for (int i = 0; i < rowsInA; i++) {
vector<int> myRow;
myRow.reserve(columnsInA);
myRow.push_back(0); // First element fixed.
for (int j = 1; j < columnsInA; j++) {
const int x = rand() % 100;;
myRow.push_back(x);
}
a.push_back(myRow);
}
Alternatively, making all the values random, and working directly with the vector:
a.reserve(rowsInA);
for (int i = 0; i < rowsInA; i++) {
a.push_back( {} );
a.back().reserve(columnsInA);
for (int j = 0; j < columnsInA; j++) {
const int x = rand() % 100;;
a.back().push_back(x);
}
}
You have a similar problem with initializing B, and your multiply loop needs to accumulate a[i][k] * b[k][j] into a temporary sum, then push that onto myRow, and finally push myRow onto d.
Finally, when you have got this working, look up how to write a Matrix class that stores all the data in a vector with rows*cols elements and then uses an indexing function to refer to it. Your cache will thank you.