Non Square Matrix Multiplication Help C++ - 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.

Related

Problem in rearranging rows and columns of an array

In general, given the task:
A permissible matrix transformation is a permutation of two adjacent rows or two neighboring columns. A real square matrix of order n (n <= 12) is given. Using valid converters, you can get a matrix in which the maximum element is in the upper left corner. Elements were used to perform valid conversions.
My problem is precisely that I cannot swap adjacent rows or columns.
Here is my code:
#include <iostream>
#include <algorithm>
using namespace std;
const int rows = 4, cols = rows;
int iMax = 0;
int jMax = 0;
int arr[rows][cols];
void arr_f()
{
setlocale(LC_ALL, "rus");
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
cin >> arr[i][j];
}
}
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
cout << " " << arr[i][j] << "\t";
if (arr[i][j] > arr[iMax][jMax])
{
iMax = i;
jMax = j;
}
}
cout << endl;
}
cout << endl << "The maximum number of array: " << arr[iMax][jMax] << endl << endl;
}
int main()
{
arr_f();
system("pause");
}
Tried to add features
inline void swap_columns(const int f, const int s)
{
for (int i = 0; i < rows; ++i)
{
swap(arr[i][f], arr[i][s]);
}
}
inline void swap_rows(const int f, const int s)
{
for (int i = 0; i < rows; ++i)
{
swap(arr[f][i], arr[s][i]);
}
}
and add the following to the arr_f () function:
swap_rows(0, iMax);
swap_columns(0, jMax);
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
cout << " " << arr[i][j] << "\t";
}
cout << endl;
}
But in this case, the rows (and columns) do not change as expected (the row in which the maximum value is located is immediately replaced by the first row, ignoring the rest).
You obtained a wrong result, because swap_columns and swap_rows make operations that are not allowed. You need to make them this way:
inline void swap_columns(const int k)
{
for (int i = 0; i < rows; ++i)
{
swap(arr[i][k], arr[i][k+1]);
}
}
inline void swap_rows(const int k)
{
for (int i = 0; i < rows; ++i)
{
swap(arr[k][i], arr[k+1][i]);
}
}
And apply this way:
for (int k = iMax-1; k >= 0; --k)
swap_rows(k);
for (int k = jMax-1; k >= 0; --k)
swap_columns(k);
Certainly, this may be improved by moving larger blocks, but this is a matter of optimization.
To swap adjacent rows and columns, just replace this:
swap_rows(0, iMax);
swap_columns(0, jMax);
with this:
swap_rows(iMax + 1, iMax);
swap_columns(jMax + 1, jMax);
However, it is not clear from the problem description, whether this would always be the desired solution. And if iMax happens to be the last row index, then iMax + 1 would be out of bounds and fail at run time. In that case, perhaps iMax - 1 would be required instead.

Dynamically Allocated 2D Array EXC_BAD_ACCESS Error in C++

I'm in the early stages of my program and right now I'm simply trying to initialize a 2D array to hold all dashes but I keep getting a ECX_BAD_ACCESS error. My code seems to work with a square array (ex: 5x5 or 6x6) but if I do 10 by 5 I get the error.
void readMatrix(char **twoDarray, int &rows, int &cols)
{
std::cout << "Enter number of rows for board";
std::cin >> rows;
std::cout << "Enter number of columns for board";
std::cin >> cols;
//dynamic 2D array initialization
twoDarray = new char*[rows];
for(int i = 0; i < cols; ++i)
twoDarray[i] = new char[rows];
//set elements of array to dashes
for(int i = 0; i < rows; ++i)
for(int j = 0; j < cols; ++j){
twoDarray[i][j] = '-';
}
//printing the array
for(int i = 0; i < rows; ++i){
std::cout << " " << std::endl;
for(int j = 0; j < cols; ++j)
std::cout << twoDarray[i][j] << " ";
}
}
Your first for-loop should go from 0 to #rows, not #cols. Also, in the body of that same loop allocate cols, not rows.

C++ 2D Array - Error invalid types ‘int[int]’ for array subscript

I am trying to create MxN matrix using 2D-arrays in C++.
The createMatrix() function asks for user input for matrix items and the printMatrix() function has to print the matrix.
But the printing task is not working (I can't access the array created, I don't understand why)
I receive the error :
matrix.cpp:35:20: error: invalid types ‘int[int]’ for array subscript
cout << matrix[i][j];
The code I'm working with is:
#include "iostream"
using namespace std;
// user input matrix
int createMatrix(int m, int n){
int arr[m][n];
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
cout << "A[" << i << "][" << j << "] : ";
cin >> arr[i][j];
}
cout << endl;
}
return arr[m][n];
}
/*
void printMatrix(int matrix[][2], int m, int n){
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
cout << matrix[i][j];
}
}
}
*/
int main(){
int m = 2, n = 2; // m = rows, n = columns
int matrix = createMatrix(m,n);
// printMatrix(matrix, m, n); // not working as sub-routine too, main target to make it work with sub-routine
// to print matrix
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
cout << matrix[i][j];
}
}
return 0;
}
matrix is an int not an int[][]. Since it is an int there is no subscript operator and that is why you are getting the error you are getting. You are also using veriable length arrays which is not standard C++. I would suggest you change your code to use a std::vector like
std::vector<std::vector<int>> createMatrix(int m, int n)
{
std::vector<std::vector<int>> arr(m, std::vector<int>(n));
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
cout << "A[" << i << "][" << j << "] : ";
cin >> arr[i][j];
}
cout << endl;
}
return arr;
}
And then main() would be:
int main(){
int m = 2, n = 2; // m = rows, n = columns
std::vector<std::vector<int>> matrix = createMatrix(m,n);
// printMatrix(matrix, m, n); // not working as sub-routine too, main target to make it work with sub-routine
// to print matrix
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
cout << matrix[i][j];
}
}
return 0;
}
Your matrix is not array. it is int.
You need to work with the pointers.
Yes, createMatrix works but you won't be able to do anything with what it created. Because:
arr[n][m] is local (and out of boundaries by the way). It is not a matrix as you probably thought but an item of arr at position [n][m].
It is not well defined to declare array of fixed sizes with vary sizes that depend on function input.
You need to pass to createMatrix array from the main() as pointer (like you did in printMatrix) and createMatrix should work with it and not something local.
Now regarding your original question:
But the printing task is not working (I can't access the array
created, I don't understand why)
matrix was defined as int, not as array.
int matrix = createMatrix(m,n);

C++ User-defined 2 dimensional array with geometrical progression

I am learning C++ by myself,by solving different problems.
I am trying to solve problem which was originally designed for Pascal in C++.
It should ask user to input 3 integers M,N and q.
Then it should make 2d array of integers with size MxN, where all the elements of (I=I,...M) line will be the members of geometrical progression with first element equal to number of line (I) and denominator q.
I wanted to create a dynamic massive, but I realized that it won't really work with two undefined integers. So, I tried vectors. I guess that I created them in a right way, but I've got no idea how to make a geometrical progression.
Here is my code:
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int m, n, q;
cout << "Enter the number for M \n";
cin >> m;
if (cin.fail())
{
cin.clear();
cin.ignore();
cout << "This is not a number! " << endl;
system("pause");
return 0;
}
cout << "Enter the number for N \n";
cin >> n;
if (cin.fail())
{
cin.clear();
cin.ignore();
cout << "This is not a number! " << endl;
system("pause");
return 0;
}
cout << "Enter the number for Q \n";
cin >> q;
if (cin.fail())
{
cin.clear();
cin.ignore();
cout << "This is not a number! " << endl;
system("pause");
return 0;
}
int** matrix;
matrix = new int*[m];
for (int i = 0; i < m; i++)
matrix[i] = new int[n];
for (int i = 0; i < m; i++)
{
matrix[i][0] = i + 1;
}
for (int i = 0; i < m; i++)
{
for (int j = 1; j < n; j++)
{
matrix[i][j] = (i + 1)*pow(i, j);
cout << matrix[i][j];
}
}
system("pause");
return 0;
}
Note: You can create a two dimensional array of a variable size, although it involves memory allocation and is slightly ugly.
int** matrix;
matrix = new int*[M];
for (int i = 0; i < M; i++)
matrix[i] = new int[N];
That's the code to create an array of size MxN.
Don't forget to deallocate your memory like so:
for (int i = 0; i < M; i++)
delete matrix[i];
delete matrix;
As far as your question about the geometric progression, I am unsure of what you are asking. When you say geometric progression do you refer to something along the lines of 2 10 50 250 etc.? I am not sure what you mean by "lines" as you don't refer to any such variable in your code.
EDIT
So once the MxN matrix is created, iterate through the rows and initialize the rows like so:
for (int i = 0; i < M; i++)
{
matrix[i][0] = i+1;
}
This should set the first column of each row to the correct number.
Then something along the lines of this should fill out the rest of the geometric progression:
for (int i = 0; i < M; i++)
{
for (int j = 1; j < N; j++)
{
matrix[i][j] = (i+1)*pow(r,j);
//note that you'll probably have to do some typecasting
//p.s. I'm not 100% sure that this is the correct formula
}
}
I think this is what you are looking for. Let me know if it works because I haven't tested it myself.
Print the matrix like this:
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
std::cout << matrix[i][j] << " ";
}
std::cout << "\n";
}

Replacing values in a 2D array

I have to create a program that allows a user to fill in a (partial) Latin Square of order 4. You can use 0's to represent empty cells. The user will give the number to place, the row and column. The number should only be placed if it does not violate the properties of a partial Latin square and it shouldn't rewrite numbers that have already been placed.
I have an matrix that is outputting all zeroes now. So next I have to replace each of these values by what the user is inputting. The problem is I don't know how to do this.
Here is my code:
#include <iostream>
using namespace std;
const int ORDER = 4;
void fill (int m[], int order);
void outputMatrix (int m[], int order);
void replaceValue (int m[], int order, int n, int row, int column);
int main(){
int matrix[ORDER];
int row;
int column;
int n;
fill (matrix, ORDER);
outputMatrix (matrix, ORDER);
do {
cout << "Enter the number to place, the row and the column, each seperated by a space: ";
cin >> n;
cin >> row;
cin >> column;
}while (n > 0 || n <= ORDER);
if (n <= 0 || n >= ORDER){
cout << "Thank you";
cout << endl;
}
return 0;
}
void fill (int m[], int order){
for (int i = 0; i < order*order; i++){
m[i] = 0;
}
}
void outputMatrix (int m[], int order){
int c = 0;
for (int i = 0; i < order*order; i++){
c++;
cout << m[i] << ' ';
if (c == order){
cout << endl;
c = 0;
}
}
cout << endl;
}
void replaceValue (int m[], int order, int n, int row, int column){
for (int i = 0; i < order; i++){
m[order] = m[row][column];
m[row][column] = n;
}
}
How do I replace values in a Matrix in C++?
If you have a matrix, matrix[row][col] = value; would do the trick. However, I see that you allocate a single array. Make sure you look at this.
EDIT:
I looked closer at you code and you are doing some things wrong.
First:
matrix[ORDER]
will create a single array of ORDER values. If you want and ORDER by ORDER matrix try:
matrix[ORDER][ORDER]
Second:
You are calling:
void fill (int m[], int order){
for (int i = 0; i < order*order; i++){
m[i] = 0;
}
}
with an of size 4 and order == 4. This will loop outside the array and give you problems.
Try something like:
matrix[ORDER][ORDER];
for (int row = 0; row != ORDER; ++row)
{
for (int col = 0; col != ORDER; ++col)
{
matrix[row][col] = 0;
}
}
Hope this helps.
You can't really write arr[i][j] if arr is defined as arr[]. There's no information about the length of the row (how many columns there are).
You could use arrays of type arr[][4], and write your functions like so:
// The & is to pass by reference.
void print(int (&arr)[][4], int length)
{
for(int i = 0; i < length; i++) {
for(int j = 0; j < 4; j++) {
cout << arr[i][j] << " ";
}
cout << endl;
}
}
But in my opinion for a low-order multidimensional array like this one, using a typedef for a vector of vectors is the better option:
typedef vector<vector<int> > Matrix;
void print(Matrix& arr)
{
for(int i = 0; i < arr.size(); i++) {
for(int j = 0; j < arr[i].size(); j++) {
cout << arr[i][j] << " ";
}
cout << endl;
}
}
In either case, writing arr[i][j] = k will behave as you expect.
The easiest way to clear/zero your matrix is that:
memset( &matrix, 0, sizeof(matrix));
;-)