Array filling mistake - c++

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

Related

syntax for outputting a 2d vector

Say if I have a 2d vector of Int:
vector <vector<Int> > myV;
Then I define 2 variables:
int rows; //number of vectors in myV. This is the my y(vertical) index.
int columns; //number of elements in one vector within myV. x index.
I want to know when I output myV like a rectangle: iterate through myV[something][something], which variable should be in the left bracket, and which should be right? I just want the variables to fit perfectly into my intention.
I also wrote a test code, but it has segmentation fault that I haven't figured out why.
#include <iostream>
#include <vector>
using namespace std;
int main(){
vector<vector<int> > myV;
for (int i = 0; i < 3; i++){
for (int j = 0; j < 3; j++){
myV[i][j] = j;
}
for (int i = 0; i < 3; i++){
for (int j = 0; j < 3; j++)
cout << myV[i][j] << " ";
cout << endl;}
}
The reason your code is not working is because you haven't allocated any memory for your vector. Change the declaration of the vector to:
vector<vector<int>> myV(3, vector<int>(3));
On a side note, I would even consider storing your array in one dimension (i.e std::vector<int> myV(9);) and compute indexes for multidimensional use using a function getIndex, which could be implemented as:
inline std::vector<int>::size_type getIndex(int numCols, int i, int j)
{
return i * numCols + j;
}
Usage of this function may look like:
for (int i = 0; i < 3; ++i)
{
for (int j = 0; j < 3; ++i)
{
myV[getIndex(3, i, j)] = /* Value */;
}
}
This would avoid the large use of memory a multidimensional vector needs, and would allow usage in pretty much the same way.
Here is some further reading for more information on why one should use 1d arrays for representing 2d arrays.

trouble iterating through multidimensional array

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
}
}

Non Square Matrix Multiplication Help C++

first off sorry for the slightly messy code as I was fiddling with different things to try to get it to work. As of now, my code can multiply Square Matrices just fine; however, it has difficulties computing Non Square Matrices. My best guess after debugging is how i re-size my vectors, and that there is an out of bounds error which causes the program to crash. Any help would be appreciated, my code should be able to Multiply any Vectors sizes withing Matrix Multiplication Rules.
I also would like to note this is a HW assignment so I am limited to how I can build my code, basically ONLY using vectors, cannot write your own class etc....
#include <iostream>
#include <vector>
using namespace std;
void multiply_matrices(vector <vector<int> > matrix1,vector <vector<int> > matrix2, int cols, int rows2);
void setMatrix(vector <vector<int> > &matrix, int rows, int cols);
int main()
{
int rows, cols, rows2, cols2;
vector< vector<int> > matrix, matrix2;
cout<<"Please enter the number of Rows and Columns for your first Matrix."<<endl;
cout<<"Rows: ";
cin>>rows;
cout<<"Columns: ";
cin>>cols;
matrix.resize(cols, vector<int>(rows,0)); //Saw this online so not sure how it works but it works, if i take out one i cant do row<column and vice versa
matrix.resize(rows, vector<int>(cols,0));
cout<<"Size has been declared, please enter data for your matrix"<<endl;
setMatrix(matrix,rows,cols);
cout<<"Second Matrix Automatically Set by Matrix Multiplication Rule"<<endl; //Just automatically sets second matrix as per Matrix Multiplication Rule
rows2=cols;
cols2=rows;
cout<<"Second Matrix Size is: " << rows2 << " by " << cols2 << endl;
matrix2.resize(cols2, vector<int>(rows2,0));
matrix2.resize(rows2, vector<int>(cols2,0));
setMatrix(matrix2,rows2,cols2);
cout<<"Multiplied Matrix is:"<<endl;
multiply_matrices(matrix,matrix2,cols,rows2);
system("PAUSE");
return 0;
}
void setMatrix(vector <vector<int> > &matrix, int rows,int cols){
int num;
for(int i = 0; i < rows; i ++)
{
for (int j = 0; j < cols; j++)
{
cout << "Enter Value for Row " << (i+1) << " Column " << (j+1) << ": ";
cin>>num;
matrix[i][j]=num;
}
cout << endl;
}
/*for(int i = 0; i < rows; i ++)
{
for (int j = 0; j < cols; j++)
{
cout << matrix[i][j] << " ";
}
cout << endl;
}
*/
}
void multiply_matrices(vector <vector<int> > matrix1,vector <vector<int> > matrix2, int cols, int rows2){
vector< vector<int> > tempMatrix;
int newrows=rows2;
int newcols=cols;
int sum;
tempMatrix.resize(newcols, vector<int>(newrows,0)); //Resizing new matrix to proper size, so if it was (2x3)(3x2), new matrix is (3x3)
for (int i = 0; i < newrows; i++) //This Works Fine for Square Matrixes but not for others, i have no clue how to fix it?
{
for (int j = 0; j < newcols; j++){
//sum=0;
for (int u = 0; u < newcols; u++)
{
//sum+=matrix1[i][u] * matrix2[u][j];
//tempMatrix[i][j]=sum;
tempMatrix[i][j] += matrix1[i][u] * matrix2[u][j];
}
}
}
for(int i = 0; i < newrows; i ++)
{
for (int j = 0; j < newcols; j++)
{
cout << tempMatrix[i][j] << " ";
}
cout << endl;
}
}
Initialize your first matrix like this:
matrix.resize(rows, vector<int>(cols,0));
and your second like this:
matrix2.resize(rows2, vector<int>(cols2,0));
where rows2 = cols. Note that there is no "multiplication rule" that implies cols2 == rows.
The problem is in your multiply_matrices function where the loops should be
for (int i = 0; i < rows; i++) // or matrix1.size()
for (int j = 0; j < cols2; j++) // or tempMatrix[i].size()
for (int u = 0; u < cols; u++) // or rows2 or matrix1[i].size()
but as already stated in the comments, it would be better to use vector::size() instead of passing the sizes as additional parameters.
Also, if you multiply (2x3)(3x2), the result is (2x2):
tempMatrix.resize(rows, vector<int>(cols2,0));
There is nothing wrong with the resize() function. What may be wrong is that you ignore the maximum size and rely solely on variables that are passed to your functions.
For example, your setMatrix function is passed rows and cols, but this is not necessary.
The function should be rewritten using only the matrix to provide the sizes to the loops:
void setMatrix(vector<vector<int> > &matrix)
{
int num;
for(int i = 0; i < matrix.size(); ++i)
{
for (int j = 0; j < matrix[i].size(); ++j)
{
cout << "Enter Value for Row " << (i+1) << " Column " << (j+1) << ": ";
cin>>num;
matrix[i][j] = num;
}
cout << endl;
}
}
You have the same issue with multiply_matrix. What you should be doing is ensure that you're loops use the return value of vector::size(), which you do not do. The problem is here:
for (int i = 0; i < newrows; i++)
{
for (int j = 0; j < newcols; j++)
{
for (int u = 0; u < newcols; u++)
{
tempMatrix[i][j] += matrix1[i][u] * matrix2[u][j];
You sized the tempMatrix to newrows rows and newcols columns. But how do you know that matrix1 and matrix2 have at least newrows rows and newcols columns? You don't know, but you just assume they do.
So you either need to ensure that the size of matrix1 and matrix2 can accommodate the number of rows/columns, or you throttle those loops to use the minimum rows/columns.
Overall, the issue is that nowhere do you use vector::size() in your code that I see. So start to use size() to your advantage -- don't create superfluous (and possibly erroneously set) variables that supposedly denote the sizes of the rows and columns.

Mean Average vector from 1D vector transposed

This has been annoying me for most of the day..
Suppose that I have the following vector:
v = [1, 2, 4, 9]
I transpose this, so the vector is in columns:
v = [1, 2
4, 9]
I do this, using the following method:
for(unsigned i=0; (i < cols); i++)
{
for(unsigned j=0; (j < 2); j++)
{
std::cout << vect[i*2+j] << " ";
}
std::cout << std::endl;
}
But how would I calculate the columns, first? My aim is to achieve the following:
(1 + 4)/2 = 2.5
(2 + 9)/2 = 5.5
Therefore, a resulting vector would return the mean matrix: x = [2.5, 5.5]
I have tried the following:
double summation = 0;
for(unsigned i=0; (i < cols); i++)
{
for(unsigned j=0; (j < size); j++)
{
summation += values[i*(i*j)+j];
}
std::cout << summation << std::endl;
}
Which produces:
3
8
I am probably missing something really stupid here, but, I can't seem to figure out what.
I have also tried to have a variable subRow which begins at 0 and increments each time by 3 but this did not work either.
Your last sentence has the right idea, but not quite the right number. Where you mention 3, it appears you need 2. That's normally called the "stride". Using it, averaging by columns would come out something like this:
for (int i=0; i<stride; i++) {
double total = 0;
for (int j=0; j<input.size(); j+=stride)
total += input[j];
result[i] = total / (j.size()/stride);
}
At least for the moment, this takes for granted that the size of the input matrix really is "correct" --i.e., an even multiple of the stride you specify.
You may find it easier to debug if keep your index calculations simple:
std::vector<int> v{1, 2, 4, 9};
const unsigned int WIDTH = 2;
for (unsigned int i = 0; i < WIDTH; ++i)
{
double sum = 0.0;
for (unsigned int j = i; j < v.size(); j += WIDTH)
{
sum += v[j];
}
// do something with sum
}
Your problem appears to be here: for(unsigned j=0; (j < size); j++)
You are starting j at 0 and increment by 1 to size() each time. Most of the values you hit will not be valid for what you are trying to do.
int v[] = {1,2,4,9};
int cols = 2;
int rows = 2;
for(int c=0 ; c < cols ; c++) {
double sum=0;
for(int r=0 ; r < rows ; r++)
sum += v[cols*r+c];
std::cout << sum /rows << std::endl;
}

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.