Creating matrix using array - c++

I made an array matrix and used for loops, the problem is that it only displays my last input. Please refer to the sample result below.
#include<iostream>
using namespace std;
int main()
{
int x = 0, y = 0;
int a[x][y], i, j;
cout<<"Enter number of Columns: ";
cin>>y;
cout<<"Enter number of Rows: ";
cin>>x;
cout<<endl;
for(i=0; i<x; i++)
{
cout<<endl;
cout<<"Enter values or row/s: ";
cout<<endl;
for(j=0; j<y; j++)
{
cout<<endl;
cout<<"Row "<< i+1 << ": ";
cin >> a[i][j];
}
}
cout<<endl;
cout<<"Entered Matrix is: ";
cout<<endl;
for(i=0; i<x; i++)
{
for(j=0; j<y; j++)
cout<<a[i][j]<<" ";
cout<<endl;
}
}
SAMPLE RESULT:
Enter number of Columns: 3
Enter number of Rows: 2
Enter values or row/s:
Row 1: -1
Row 1: -2
Row 1: -3
Enter values or row/s:
Row 2: 4
Row 2: 5
Row 2: -6
Entered Matrix is:
4 5 -6
4 5 -6

Just change declaration of array like this:
int[x][y] to int[10][10]

The problem here is that you want to use arrays with a variable size. So, input "x" and "y" and then use this as the array size. (array[x][y])
This does not work in C++. There are no dynamic, so called VLAs (Variable Length Arrays) in C++.
There are some dialects or compiler extensions, which can handle VLA, but C++ does not allow VLAs.
This means, you cannot write somthing like:
int arraySize{};
std::cin >> arraySize;
int array[arraySize];
This is invalid C++ code.
C-Style arrays must have a compile time constant value. You can define it with const or constexpr or even a number literal like 42. Magic constants liek 42 or the worst solution. Anyway, you could write
constepxr int arraySize = 42;
int array[arraySize];
This is syntactically correct.
But, it will not help you. Because you need something "dynamic". The idiomatic correct approach in C++ is to use a std::vector. Please read here about that. And using a 2d std::vector the C++ solution would look like that:
#include <iostream>
#include <vector>
int main() {
// Get user input. Size of matrix. Number of rows and columns
std::cout << "\nEnter number of Rows: ";
if (size_t numberOfRows{}; (std::cin >> numberOfRows) and (numberOfRows > 0)) {
std::cout << "\nEnter number of columns: ";
if (size_t numberOfColumns{}; (std::cin >> numberOfColumns) and (numberOfColumns > 0)) {
// Define 2d matrix and initialze all values to 0
std::vector<std::vector<int>> matrix(numberOfRows, std::vector<int>(numberOfColumns, 0));
// Read all values of matrix
std::cout << "\n\Please enter matrix values in row-column order:\n";
for (std::vector<int>& row : matrix)
for (int& column : row)
std::cin >> column;
// Now show matrix
std::cout << "\n\nThe entered Matrix is:\n\n";
for (std::vector<int>& row : matrix) {
for (int& column : row) std::cout << column << ' ';
std::cout << '\n';
}
}
}
}
But, next, we often hear the statement that you did not learn about std::vector yet. And then, you need to use the approach to use old style memory allocation using new and delete. This is a non-recommend approach, but for teaching purposes, it is still often used.
So, you first allocate memory that will hold pointers to array (for the rows) and then allocate memory for the columns in the rows.
This would then look like the below:
#include <iostream>
int main() {
// Get user input. Size of matrix. Number of rows and columns
std::cout << "\nEnter number of Rows: ";
if (size_t numberOfRows{}; (std::cin >> numberOfRows) and (numberOfRows > 0)) {
std::cout << "\nEnter number of columns: ";
if (size_t numberOfColumns{}; (std::cin >> numberOfColumns) and (numberOfColumns > 0)) {
// Define 2d matrix
int** matrix;
matrix = new int* [numberOfRows];
for (int row = 0; row < numberOfRows; ++row)
matrix[row] = new int[numberOfColumns];
// Read all values of matrix
std::cout << "\n\Please enter matrix values in row-column order:\n";
for (int row = 0; row < numberOfRows; ++row)
for (int column=0; column < numberOfColumns; ++column)
std::cin >> matrix[row][column];
// Now show matrix
std::cout << "\n\nThe entered Matrix is:\n\n";
for (int row = 0; row < numberOfRows; ++row) {
for (int column = 0; column < numberOfColumns; ++column) std::cout << matrix[row][column] << ' ';
std::cout << '\n';
}
// Release memory
for (int row = 0; row < numberOfRows; ++row)
delete [] matrix[row];
delete matrix;
}
}
}
As said, often teached, but strongly discouraged.

Related

Summing 2D array columns in c++ [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I want to sum up columns of a predefined 2 D array, but my code seems not to work. E. g. for a 2D array with rows 2 3 and 4 5
I am getting following column sums:
-117393687 and -113194156
Here is the part of my code where I sum up the columns:
//sum columns
for(i=0; i<m; i++)
{
for(ii=0; ii<m; ii++)
{
sum += myarray[i][ii];
}
cout <<"column sum: "<<sum<<endl;
{
Rest of my code:
#include <iostream>
using namespace std;
int main()
{
int i, ii, n, m, sum;
int array[n][m];
sum=0;
cout <"no. of rows"<<endl;
cin>>n;
cout <"no. of columns"<<endl;
cin>>m;
for(i=0; i<n; i++)
{
for(ii=0; ii<n; ii++)
{
cout<<"row "<<i+1<<" column "<<ii+1<<endl;
cin>>array[n][m];
}
}
}
//sum columns
for(i=0; i<m; i++)
{
for(ii=0; ii<m; ii++)
{
sum += myarray[i][ii];
}
cout <<"column sum: "<<sum<<endl;
{
There are quite a few errors on your code, and it has quite a weird structure, but trying not to change it too much (so it's still easy for you to follow the fixes), let's see it fixed then I'll explain it (please note that this version will compile and run in practice):
#include <iostream>
using namespace std;
int main()
{
int i, ii, n, m, sum;
cout << "no. of rows" << endl;
cin >> n;
cout << "no. of columns" << endl;
cin >> m;
int array[n][m];
for (i=0; i<n; i++)
{
for (ii=0; ii<m; ii++)
{
cout << "row " << i+1 << " column " << ii+1 << endl;
cin >> array[i][ii];
}
}
sum=0;
for (i=0; i<n; i++)
{
for (ii=0; ii<m; ii++)
{
sum += array[i][ii];
}
}
cout << "Sum: " << sum << endl;
}
Ok, so, first, you should only declare the array after you know what "n" and "m" variables are. Edit: also, not all compilers will accept declaring the dynamic array that way, but again, I tried to keep your original structure as much as possible.
Second, in your input loop, you should index the array by "i" and "ii", but you were always indexing by "n" and "m", that is, only writing to the latest index, which would even cause an exception.
Last, while summing, again you should use "i" and "ii" as array indices, so you correctly scan the array.
And that is it.
You're not declaring your array size properly. When you create the array n and m aren't set yet. You need to determine their size first. And even then you have to pass in constants to an array because arrays in C++ cannot be dynamically sized. If you want the user to determine container size like this then use a vector of vectors. Arrays are to be used when you know the size from the beginning of the program.
According to the code shown above:
You are mistaking while taking the iputs. Try this:
for(i=0; i<n; i++)
{
for(ii=0; ii<n; ii++)
{
cout<<"row "<<i+1<<" column "<<ii+1<<endl;
cin>>array[i][ii];
}
}
You are initializing the 2D array in a wrong way, you need to define the size first, m and n are not initalized when declaring the array.
On C++ using containers like vector is better.
You also had a error in the input code (2 n instead of n and m in the for loop).
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int rows, cols, sum = 0;
std::vector<std::vector<int>> array;
cout << "No. of rows: ";
cin >> rows;
cout << "No. of columns: ";
cin >> cols;
for(int i = 0; i< rows; i++)
{
std::vector<int> v;
for(int j = 0; j < cols; j++)
{
cout << "Value for row " << i + 1 << " and column "<< j + 1 << ": ";
int val;
cin >> val;
v.push_back(val);
}
array.push_back(v);
}
for (auto i: array)
{
for(auto j: i)
{
sum += j;
}
}
cout << "The sum is: " << sum << endl;
}

Why "std::cin >> secondMatrix[i*twoColoumn + j];" give me segmentation fault

Language:c++
System:Linux:
Compile:g++ prog.cpp -o prog
Here is the problem. I have a program that let the user insert the size of two matrices(I'm keeping the matrices 1D instead of 2D as an exercise).The part of the code that is giving me problems is usually fine, except when i put in input:
2
1
1
1
When I do this, the output is segmentation fault between printf("4") and printf("5").
#include <iostream>
int main(void)
{
int oneColoumn, oneRow, twoColoumn, twoRow;
std::cout << "\nHow many coloumns do you want for the first matrix?" << std::endl;
std::cin >> oneColoumn;
std::cout << "\nHow many rows do you want for the first matrix?" << std::endl;
std::cin >> oneRow;
std::cout << "\nHow many coloumns do you want for the second matrix?" << std::endl;
std::cin >> twoColoumn;
std::cout << "\nHow many rows do you want for the second matrix?" << std::endl;
std::cin >> twoRow;
int firstMatrix[oneColoumn*oneRow];
int secondMatrix[twoColoumn*twoRow];
for(int i=0; i < oneColoumn; i++)
{
for(int j=0; j < oneRow; j++)
{
std::cout << "Insert a number for the first matrix";
std::cin >> firstMatrix[i*oneColoumn + j];
}
}
printf("1");
for(int i=0; i < twoColoumn; i++)
{printf("2");
for(int j=0; j < twoRow; j++)
{printf("3");
std::cout << "Insert a number for the second matrix";
printf("4");
std::cin >> secondMatrix[i*twoColoumn + j];
printf("5");
}
}
int threeColoumn, threeRow;
if(oneColoumn>twoColoumn)
threeColoumn=twoColoumn;
if(oneRow>twoRow)
threeRow=twoRow;
int thirdMatrix[threeColoumn*threeRow];
char choice;
std::cout<<"Do you want to add or multiply the two matrices?(a/m)"<<std::endl;
std::cin>>choice;
if(choice=='a')
{
std::cout<<"The two matrices have been added"<<std::endl;
//Addition(firstMatrix,oneRow,oneColoumn,secondMatrix,twoRow,twoColoumn,thirdMatrix,threeRow,threeColoumn);
}
else if(choice=='m')
{
std::cout<<"The two matrices have been multiplied"<<std::endl;
//Multiplication(firstMatrix,oneRow,oneColoumn,secondMatrix,twoRow,twoColoumn,thirdMatrix,threeRow,threeColoumn);
}
}
You have an array indexing issue:
for(int i=0; i < oneColoumn; i++)
{
for(int j=0; j < oneRow; j++)
{
std::cout << "Insert a number for the first matrix";
std::cin >> firstMatrix[i*oneColoumn + j];
}
}
After one completion of the inner loop, you iterate oneRow times.
After two completions of the inner loop, you have iterated 2*oneRow times.
...
etc
You want:
firstMatrix[i*oneRow + j]
Additionally, as others have pointed out, the following two lines declare your arrays on the stack as VLAs (variable length arrays) because the values oneColumn and oneRow are provided by the user and are not known until runtime.
int firstMatrix[oneColoumn*oneRow];
int secondMatrix[twoColoumn*twoRow];
This is not necessarily supported, but may be depending on your compiler. For gcc, see https://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html. And also see this: What's the difference between a VLA and dynamic memory allocation via malloc?

Search best match of an array into a matrix using std::vector

I've just completed a program which does as follows:
You have t[10][5] and p[10] arrays.
You read dimT and dimP.
You write dimT values in t[][] and dimP values in p[].
For writing values in t[][], you have to fill lines before. The output must be the column which has highest number of matches for the p[] array.
Example:
INPUT -> 14 (dimT) 2 (dimP) 0 1 2 3 4 0 2 7 9 1 0 11 12 0 (t[][]) 0 0 (p[])
So the final matrix display is:
0 1 2 3 4
0 2 7 9 1
0 11 12 0
OUTPUT -> The best matching column is 0 with 2 matches (overlap counted).
I created this program using arrays but it's really horrible, so I'm looking for a better and cleaner solution from some experts possibly, using vectors instead of simple arrays.
Here is my current code. It would be better if I had split it into a function or two more, but it is shorter this way:
#include <iostream>
#include <vector>
using namespace std;
bool IsMatch(vector<double>& col, vector<double>& p, int n)
{
for (size_t i=0; i<p.size() ;i++)
if (col[i+n]!=p[i])
return false;
return true;
}
int main()
{
int dimT;
int dimP;
cin >> dimT;
cin >> dimP;
int lineN = (dimT+5-1)/5;
vector<vector<double> > t(lineN,vector<double>(5));
vector<vector<double> > tTran(5,vector<double>());
vector<double> p(dimP);
t[lineN-1].resize(dimT%5);
//input matrices
for (int i=0; i<dimT;i++) {
double inputVal;
cin >> inputVal;
tTran[i%5].push_back(inputVal);
t[i/5][i%5]=inputVal;
}
for (int i=0; i<dimP;i++)
cin >> p[i];
//print it out
for (int line=0; line<lineN; line++){
for (size_t j=0; j<t[line].size(); j++)
cout << t[line][j] << " ";
cout << endl;
}
//transpose t
/*vector<vector<double> > tTran(5,vector<double>());
for (int line=0; line<lineN; line++)
for (size_t j=0; j<t[line].size(); j++)
tTran[j].push_back(t[line][j]);
//output tTran
for (int line=0; line<5; line++){
for (size_t j=0; j<tTran[line].size(); j++)
cout << tTran[line][j] << " ";
cout << endl;
}
*/
int maxCol=0;
int maxMatchN=0;
for (int col=0; col<5; col++){
int matchN=0;
for (size_t j=0; j<tTran[col].size()-p.size()+1; j++)
if (IsMatch(tTran[col],p,j) )
matchN++;
if (matchN>maxMatchN){
maxMatchN = matchN;
maxCol = col;
}
}
cout << "The best matching column is " << maxCol
<< " with " << maxMatchN << " matches (overlap counted)." << endl;
}
Here is the simpler (all transposed) version I was suggesting in the comments: The point I'm trying to show is that the non transposed copy has no value. You understood it is easier to transpose during input than later. But you kept the non transposed copy as well, and did the output from the non transposed copy and processing from transposed copy.
Take a look at all the extra nonsense that can be skipped if you don't have a non transposed copy. Then compare the output loop directly from the transposed copy to the original output loop. The change to the output loop was trivial and the benefit significant.
int main()
{
int dimT;
int dimP;
cin >> dimT;
cin >> dimP;
vector<double> t[5+1]; // +1 because empty guard vector makes output loop simpler
vector<double> p(dimP);
//input matrices
for (int i=0; i<dimT;i++) {
double inputVal;
cin >> inputVal;
t[i%5].push_back(inputVal);
}
for (int i=0; i<dimP;i++)
cin >> p[i];
//print it out
for (size_t line=0; line<t[0].size(); line++){
for (size_t j=0; line<t[j].size(); j++)
cout << t[j][line] << " ";
cout << endl;
}
int maxCol=0;
int maxMatchN=0;
for (int col=0; col<5; col++){
int matchN=0;
for (size_t j=0; j<t[col].size()-p.size()+1; j++)
if (IsMatch(t[col],p,j) )
matchN++;
if (matchN>maxMatchN){
maxMatchN = matchN;
maxCol = col;
}
}
cout << "The best matching column is " << maxCol
<< " with " << maxMatchN << " matches (overlap counted)." << endl;
}
That empty "guard" vector is a useful trick to know and in more complicated problems avoids a lot of detail and likely mistakes. In this code it just saved needing j<5 && in one spot.

ask the user to input the values 1 row at a time of 2d array

Write a program that asks the user to input the
dimension (n) of the square (n x n) array, and then asks the user to input the values 1 row
at a time. For example:
“Enter the size of a 2D array: ”
“Enter the values in the array for row 1, separated by a space, and press enter: ”
- Limit the size of the array to maximum 10 x 10 and check for errors.
Once the array is initialized, check if there is any negative element in the array and display the result:
 If there is no negative value: “All values are non-negative!”
 If there are # negative values: “There are # negative values!” … where # is the
number of negative values found.
Example runs:
Enter the size of a 2D array: 4
Enter the values in the array for row 1, separated by a space, and press enter: 1 5 6 3
Enter the values in the array for row 2, separated by a space, and press enter: -5 6 -12 5
Enter the values in the array for row 3, separated by a space, and press enter: 9 4 -3 1
Enter the values in the array for row 4, separated by a space, and press enter: 7 5 -3 9
There are 4 negative values!
Enter the size of a 2D array: 12
ERROR: your array is too large! Enter 1 to 10
Here is what I have so far but I can't figure how to enter the info one row at a time.
Do I enter the values of into two separate arrays then try to combine them? But the values need to stay in their receptive rows.
Thanks
#include <iostream>
#include <string>
using namespace std;
int main()
{
int num;
cout << "please enter the size of the 2D array" << endl;
cin >> num;
while (num < 1 || num > 10)
{
cout << "You have entered an invalid number that is less than 10"<< endl;
cout << "Enter a new # " << endl;
cin >> num;
}
cout <<"Enter a sequence of numbers separated by spaces" << endl;
int c = 0;
int arr[num][num];
for(int i = 0; i < num; i++)
{
for(int j = 0; j < num; j++)
{
cin >> arr[i][j];
if(arr[i][j] < 0 )
{
c = c+1;
}
}
}
for(int i=0; i < num; i++)
{
for(int j=0; j < num; j++)
{
cout << arr[i][j] << endl;
}
}
cout << c << endl;
return 0;
}
With your code, it is already capable of reading one row of integers each time. In fact you can type in each integer and press enter and then type in the next...and so on. You can also type in a whole row of integers, the program will accept it as long as the count is correct.
For example, if I want to type in a 2x2 array,
I can either type in:
1
2
3
4
or do:
1 2
3 4
It will both work.
A couple of things:
Since the dimension of the array is dynamic, this line isn't valid (see this link for more: http://www.learncpp.com/cpp-tutorial/69-dynamic-memory-allocation-with-new-and-delete/):
int arr[num][num];
As such, you need either an array of pointers (which point to arrays), or a vector with which to allocate and manage the memory (given that this is an assignment, you may not be able to use a vector, and will have to use a pointer instead).
Regarding your question:
Do I enter the values of into two separate arrays then try to combine
them?
You don't have to do so.
If you use a pointer (technically: an array of pointers which point to arrays) or a vector, then you should be able to directly access and modify the contents at a particular row and column index.
Example: if you're going the pointer route:
#include <iostream>
#include <cstdlib>
int main() {
std::size_t size;
std::cout << "Enter a dimension: " << std::endl;
std::cin >> size;
int **arr = new int*[size];
//allocate the memory for the columns:
for (int i = 0; i < size; ++i) {
//remember, it's an array of pointers which in turn point to arrays
//so, that's why we have to allocate the memory for each row manually
arr[i] = new int[size];
}
//now you can alter the data in the array:
for (int i = 0; i < size; ++i) {
//the following for loop is how you would prompt the user to enter the value for a specific row:
for (int j = 0; j < size; ++j) {
std::cout << "Enter a value for row " << i << " and column " << j << std::endl;
std::cin >> arr[i][j];
}
}
//now print the entire thing:
for (int i = 0; i < size; ++i) {
for (int j = 0; j < size; ++j) {
std::cout << arr[i][j] << " ";
}
//print a new line at the end of each row:
std::cout << std::endl;
}
//free the memory we've allocated:
for (int i = 0; i < size; ++i) {
delete [] arr[i];
}
delete [] arr;
return 0;
}
However, as you've noticed: this has a lot of boilerplate code. If the option is available to you, it's arguably a better idea to use a vector instead.
For more on that discussion, consult these:
When would you use an array rather than a vector/string?
When to use vectors and when to use arrays in C++?

Multi Dimension Arrays issue

OK so basically i want this code to get the user to input a value each time into the array and they get to specify the amount of rows and columns. I think i that the problem is that each time the user enters the value it goes into the correct column but also into both rows so by the end it only prints out the last lot of numbers the user had entered in all of the rows.
Sorry if that was hard to understand as this is my first post to this site and as you can probably tell i am only learning c++. So if you could help it would be greatly appreciated.
#include <iostream>
using namespace std;
int main()
{
int row;
int column;
int value[row][column];
cout << "How Many Rows?\n";
cin >> row;
cout << "How Many Columns\n";
cin >> column;
for(int x = 0; x<row; x++) {
for(int y = 0; y<column; y++) {
cout << "Enter Value Now\n";
cin >> value[x][y];
}
cout << endl;
}
cout << endl;
for(int a = 0; a < row; a++) {
for(int b = 0; b < column; b++) {
cout << value[a][b] << " ";
}
cout << endl;
}
}
int value[row][column];
declares an array whose dimensions are based on 2 uninitialised values.
If you don't have to use a C-style array, you could use
std::vector<std::vector<int>> value;
and choose its dimensions based on user input.
Alternatively, you could continue to use a C-style array if you allocate it like
int** value;
// input row/column
value = new int*[row];
for (int i=0; i<row; i++) {
value[i] = new int[column];
}
If you use the latter approach, make sure to also delete all dynamically allocated memory later.