Replace vector in matrix using malloc and pointer - c++

My task is to replace elements of vector and elements on diagonal matrix. Vector is entered by user and the matrix is random. For example, I write vector:
1 2 3
And the random matrix is
7 0 0
0 3 0
0 0 8
I must get this
1) 7 3 8
2)
1 0 0
0 2 0
0 0 3
The first part of it i got, but the second I'm stacked. Here is entering vector:
int size;
std::cout << ("Enter the dimentoinal of vector and matrix (enter one number): ");
std::cin >> size;
int * arrayPtr = (int*) calloc(size,sizeof(int));
if (arrayPtr == NULL) exit (1);
for (int ix = 0; ix < size; ix++)
{
std::cout << "Enter element #" << ix<< " ";
std::cin >> arrayPtr[ix];
}
system ("clear") ;
std::cout << "\n\nResulting vector is:\n[ ";
for (int ix = 0; ix < size; ix++)
{
std::cout << arrayPtr[ix] << " ";
}
cout << "]\n\n\n" ;
Here is code, that not working(on the screen is not correct result):
cout << "The new matrix is :\n" ;
int * matr_n = (int*) calloc(size,sizeof(int));
cout << "\n" ;
for (int ix = 0 ; ix<size; ix++)
{
matr_n = &arrayPtr[ix] ;
cout << *matr_n << " " ;
for (int i = 0; i<size; i++)
{
cout << "\n" ;
for (int j = 0; j<size; j++)
{
if (i==j)
{
cout << *matr_n << " " ;
}
else
cout << 0 << " " ;
}
}
}
I know that the problem is in using pointers or malloc/calloc function, but for beginner is hard to catch it fast.
Can you fix it, please?

The inner for-loop which prints the matrix should be separated from the loop which calculates its values.
In other words, you'll need to change the bottom part of the code as follows:
for (int ix = 0; ix < size; ix++)
{
matr_n = &arrayPtr[ix];
std::cout << *matr_n << " ";
}
for (int i = 0; i<size; i++)
{
std::cout << "\n";
for (int j = 0; j<size; j++)
{
if (i == j)
{
std::cout << *matr_n << " ";
}
else
std::cout << 0 << " ";
}
}

Related

Print 2D array in reverse (C++)

Write a program that reads 12 integers into a 2D integer array with 4 rows and 3 columns. The program then outputs the 2D array in reverse order according to both rows and columns.
Ex: If the input is:
5 7 3
6 4 3
5 6 9
5 2 8
then the output is:
8 2 5
9 6 5
3 4 6
3 7 5
For coding simplicity, output a space after every integer, including the last one on each row.
#include <iostream>
using namespace std;
int main() {
const int ROWS = 4;
const int COLS = 3;
int arr[ROWS][COLS];
int i, j;
for(i = 0; i < ROWS; i++){
for(j = 0; j < COLS; j++){
cin>>arr[i][j];
}
}
cout << arr[3][2] << " " << arr[3][1] << " " << arr[3][0] << " " << endl;
cout << arr[2][2] << " " << arr[2][1] << " " << arr[2][0] << " "<< endl;
cout << arr[1][2] << " " << arr[1][1] << " " << arr[1][0] << " "<< endl;
cout << arr[0][2] << " " << arr[0][1] << " " << arr[0][0] << " "<< endl;
return 0;
}
I ended up having to hardcode this question because I couldnt find a way to reverse the 2D array with a loop and get it to be outputted in the form of a graph. Is there a way i could reverse the 2D array using for loops and would it be possible to be able to change the amount of rows and columns and still output the corresponding graph of values?
try this:
#include <iostream>
using namespace std;
int main() {
const int ROWS = 4;
const int COLS = 3;
int arr[ROWS][COLS];
int i, j;
for (i = 0; i < ROWS; i++) {
for (j = 0; j < COLS; j++) {
cin >> arr[i][j];
}
}
// output the reversed array
for (int i = ROWS - 1; i >= 0; i--) {
for (int j = COLS - 1; j >= 0; j--) {
cout << arr[i][j] << " ";
}
cout << endl;
}
return 0;
}
You can reverse a 2D array using nested for loops, try
#include <iostream>
using namespace std;
int main() {
const int ROWS = 4;
const int COLS = 3;
int arr[ROWS][COLS];
int i, j;
// Input the values into the 2D array
for(i = 0; i < ROWS; i++) {
for(j = 0; j < COLS; j++) {
cin >> arr[i][j];
}
}
// Reverse the rows and columns of the 2D array
for(i = ROWS - 1; i >= 0; i--) {
for(j = COLS - 1; j >= 0; j--) {
cout << arr[i][j] << " ";
}
cout << endl;
}
return 0;
}
As mentioned in comments below if you don't know ROWS and COLS size at compile time dynamically allocate the memory for 2D array(arr) in C++ using new operator.
There is very little point reading the data into a 2D array for this program. A std::vector would do the trick, sized with ROWS * COLS values. You then have the benefit of being able to read those dimensions from the user, which addresses the second part of your question.
size_t size = ROWS * COLS;
// Read data
std::vector<int> data;
data.reserve(size);
for (int value; std::cin >> value; )
{
data.push_back(value);
}
// Validate data
if (data.size() != size)
{
std::cerr << "Unexpected end of input!\n";
return EXIT_FAILURE;
}
When outputting, you can use a reverse iterator through the vector, and simply write a newline every COLS values.
// Output in reverse
int col = 0;
for (auto it = data.rbegin(); it != data.rend(); it++)
{
std::cout << *it << " ";
if (++col == COLS)
{
std::cout << "\n";
col = 0;
}
}
You can even easily fix the "space at the end of the line" problem by adjusting your output loop as follows:
// Output in reverse
int col = 0;
for (auto it = data.rbegin(); it != data.rend(); it++)
{
std::cout << *it;
if (++col == COLS)
{
std::cout << "\n";
col = 0;
}
else
{
std::cout << " ";
}
}

Sum of rows and column in a Matrix

the problem arises when I use a different number of rows and columns, for example, 2 by 3 otherwise, it is running okay. the sum of column outputs garbage values
I can't seem to understand where the bug is.
#include <iostream>
#include <conio.h>
using namespace std;
int main ()
{
int a[10][10];
int i,row,column, j, s = 0, sum = 0;
cout<<"Enter Number of rows: ";
cin>>row;
cout<<"Enter Number of columns: ";
cin>>column;
cout<< "Enter elements Matrix \n";
for (i = 0; i < row; i++)
for (j = 0; j < column; j++)
cin >> a[i][j];
cout << "Matrix Entered By you is \n";
for (i = 0; i < row; i++)
{
for (j = 0; j <column; j++)
cout << a[i][j] << " ";
cout << endl;
}
for (i = 0; i < row; i++)
{
for (j = 0; j <column; j++)
s = s + a[i][j];
cout << "Sum of Row " << i + 1 << " is: " << s;
s = 0;
cout << endl;
}
cout << endl;
for (i = 0; i < row; i++)
{
for (j = 0; j < column; j++)
s = s + a[j][i];
cout << "Sum of Column " << i + 1 << " is: " << s;
s = 0;
cout << endl;
}
}
You are not iterating correctly to get your columns sum, column and row are switched up. change to:
for (i = 0; i < column; i++) // <-----
{
for (j = 0; j < row; j++) // <-----
s = s + a[j][i];
cout << "Sum of Column " << i + 1 << " is: " << s;
s = 0;
cout << endl;
}
Consider a 3x4 matrix:
1 2 3 4
1 2 3 4
1 2 3 4
Your current loop would access it in the following manner, invoking undefined behavior.
[1] [2] [3] 4
[1] [2] [3] 4
[1] [2] [3] 4
[?] [?] [?]

How to print one side of the diagonal of an array?

Lets suppose we have a 5 X 5 random array
1 2 3 7 8
4 7 3 6 5
2 9 8 4 2
2 9 5 4 7
3 7 1 9 8
Now I want to print the right side of the diagonal shown above, along with the elements in the diagonal, like
----------8
--------6 5
------8 4 2
---9 5 4 7
3 7 1 9 8
The code I've written is
#include <iostream>
#include <time.h>
using namespace std;
int main(){
int rows, columns;
cout << "Enter rows: ";
cin >> rows;
cout << "Enter colums: ";
cin >> columns;
int **array = new int *[rows]; // generating a random array
for(int i = 0; i < rows; i++)
array[i] = new int[columns];
srand((unsigned int)time(NULL)); // random values to array
for(int i = 0; i < rows; i++){ // loop for generating a random array
for(int j = 0; j < columns; j++){
array[i][j] = rand() % 10; // range of randoms
cout << array[i][j] << " ";
}
cout << "\n";
}
cout << "For finding Max: " << endl;
for(int i = 0; i < rows; i++){//loop for the elements on the left of
for(int j = columns; j > i; j--){//diagonal including the diagonal
cout << array[i][j] << " ";
}
cout << "\n";
}
cout << "For finding Min: " << endl;
for(int i = rows; i >= 0; i++){ //loop for the lower side of
for(int j = 0; j < i - columns; j++){ //the diagonal
cout << array[i][j] << " ";
}
cout << "\n";
}
return 0;
}
After running the code the shape I get is correct , but the elements do not correspond to the main array. I have no idea what the problem is.
Left side:
for (size_t i = 0; i < rows; i++) {
for(size_t j = 0; j < columns - i; j++) {
cout << array[i][j] << " ";
}
cout << "\n";
}
Right side:
for (size_t i = 0; i < rows; i++) {
for (size_t j = 0; j < columns; j++) {
if (j < columns - i - 1) cout << "- ";
else cout << vec[i][j] << " ";
}
cout << "\n";
}

Pthreads creation is not working properly

So this program should compute a row of result matrix. But my code doesn't do what it supposed to.
#include <iostream>
#include <fstream>
#include <pthread.h>
#include <ctime>
#include <regex>
using namespace std;
//matrix A and B, result will be store as matrix C
int A[10000][10000], B[10000][10000], C[10000][10000];
int rowFirst, columnFirst, rowSecond, columnSecond;
int numThread;
struct threadLine {
int tid;
int lineNum;
int rowFirst;
int rowSecond;
int columnFirst;
int columnSecond;
};
//function to multiply matrix A and B
void* matrix (void* lineNumber)
{
int i, j, k;
int line = (long)lineNumber;
// Multiplying matrix A and B and store it in matrix C.
// per row
//for(i = 0; i < line; ++i)
//{
for(j = 0; j < columnSecond; ++j)
{
C[i][j] = 0;
for(k = 0; k < columnFirst; ++k)
{
C[i][j] += A[line][k] * B[k][j];
}
//C[i][j] = temp;
}
//}
return 0;
}
int main()
{
//read the file called matrix
ifstream read("matrix.txt");
// if it can read
if (read)
{
read >> rowFirst >> columnFirst; //read the first matrix
//thread ids
pthread_t tid[rowFirst];
struct threadLine tl[rowFirst];
for (int i = 0; i < rowFirst; i++)
{
for(int j = 0; j < columnFirst; j++)
{
read >>A[i][j]; //store it in array A
}
}
read >> rowSecond >> columnSecond; //read the second matrix
if (columnFirst != rowSecond) //column of first matrix must be the same as the second one
{
cout << "column of first matrix must have the same value as row of second matrix" << endl;
return -1;
}
else
{
for (int i = 0; i < rowSecond; i++)
{
for(int j = 0; j < columnSecond; j++)
{
read >>B[i][j]; //store it in array B
}
}
//print input data
cout << "Matrix A: "; //print array A
for (int i = 0; i < rowFirst; i++)
{
for(int j = 0; j < columnFirst; j++)
{
cout << A[i][j] << ' ';
}
cout << endl;
}
cout << "Matrix B: "; //print array B
for (int i = 0; i < rowSecond; i++)
{
for(int j = 0; j < columnSecond; j++)
{
cout << B[i][j] << ' ';
}
cout << endl;
}
cout << endl;
int timeStart = clock(); //start time counting
//loop for creating threads based on number of row (calculate per row)
for (int x = 0; x < rowFirst; x++)
{
int idSuccess = pthread_create(&tid[x], NULL, matrix, (void *) x);
cout << "Created worker thread " << tid[x] << " for row " << x << endl;
//check to see if thread is created sucessfully
if (idSuccess)
{
cout << "Thread creation failed : " << strerror(idSuccess);
return idSuccess;
}
}
cout << endl;
//wait for every threads complete
for (int x = 0; x < rowFirst; x++)
{
pthread_join(tid[x], NULL);
}
int timeStop = clock(); //stop time counting
cout << "Matrix C = A x B: "; //display result
for (int i = 0; i < rowFirst; i++)
{
for(int j = 0; j < columnSecond; j++)
{
cout << C[i][j] << " ";
if(j == columnSecond - 1)
{
cout << endl;
}
}
}
cout << endl;
//print out time
double timeVal = (timeStop -
timeStart)/double(CLOCKS_PER_SEC)*1000;
cout << "Total execution time using " << numThread << " threads is " << timeVal << " ms."<< endl;
}
}
else if(!read)
{
cout << "Unable to read file" << endl;
}
}
I was expecting the output would be something like this:
Matrix C = A x B: 3 17 10 11
2 -10 -6 -7
16 11 5 -5
4 52 30 27
Instead I got this:
Matrix C = A x B: 4 52 30 27
0 0 0 0
0 0 0 0
0 0 0 0
It only computes the first row. I'm not sure what's the cause of this.

Getting the Average,Min, and Max of numbers in 2D array

I have a problem with getting the min,max, and average of an elements of 2D array.
I have a 2D array which contains Students and Grades.
I am generating the grades with rand. For example When I enter 2,2 it prints me out
Courses : 01 02 Average Min Max
ID
01 8 50 29
02 74 59 29
, My average function takes the first ones average and doesnt take the others average.
Here is my code ;
int A[30][30];
int findAverage(int noOfStudents ,int noOfGrades ){
float sum,average;
for (int i = 0 ; i < noOfGrades ; i++) {
for (int j = 0; j<noOfStudents; j++) {
sum += A[i][j];
}
average = sum / noOfGrades;
// cout << " " << format(average);
sum = 0;
return format(average);
}
and here how I use it
int main() {
int noOfCourses , noOfStudents;
cin >> noOfCourses >> noOfStudents;
cout << "Courses : " ;
for (int i = 0; i < noOfCourses; i++) {
if (i+1 >= 10) {
cout << i+1 << " ";
}else{
cout <<"0" << i+1 << " ";
}
}
cout << "Average Min Max";
for(int i=0; i<noOfStudents; i++) { //This loops on the rows.
for(int j=0; j<noOfCourses; j++) { //This loops on the columns
A[i][j] = genGrade();
}
}
cout << "\n ID " << endl;
for(int i=0; i<noOfStudents; i++) { //This loops on the rows.
if (i+1 >= 10) {
cout <<" " << i+1 << " ";
}else{
cout <<" 0" << i+1 << " ";
}
//cout <<" 0" << i+1 << " ";
for(int j=0; j<noOfCourses; j++) { //This loops on the columns
if (A[i][j] >= 10 && A[i][j] <=99) {
cout <<" " << A[i][j] << " ";
}
if(A[i][j] < 10) {
cout <<" " << A[i][j] << " ";
}
if (A[i][j] == 100) {
cout << A[i][j] << " ";
}
}
cout <<" "<<findAverage(noOfStudents,noOfCourses);
cout << endl;
}
}
What am I doing wrong ? Also How could I get the min,max of the per array?
I would strong recommend using containers for this task. For example you could do the following
typedef std::vector<float> grades;
std::vector<grades> student_grades;
//populate
for(const grades& gr : student_grades) {
float min, max, avg;
std::tie(min, max)=std::minmax(gr.begin(), gr.end());
avg=std::accumulate(gr.begin(), gr.end(), 0.0) / gr.size());
std::cout << "Min" << min << " Max: " << max << " Avg: " << avg << std::endl;
}
http://en.cppreference.com/w/cpp/algorithm/minmax
http://en.cppreference.com/w/cpp/algorithm/accumulate
http://en.cppreference.com/w/cpp/utility/tuple/tie
For starters, you are returning from inside your loop:
for (int i = 0 ; i < noOfGrades ; i++) {
for (int j = 0; j<noOfStudents; j++) {
...
}
...
return ...;
}
Can you see how the outer loop will only ever execute once?
The problem is that in your findAverage function you have a return statement within the loop that is looping through the rows. If you want a very simple fix add another parameter to the findAverage function that indicates which row to calculate the average for.
int findAverage(int course ,int noOfGrades ){
float sum,average;
for (int j = 0; j<noOfStudents; j++) {
sum += A[course][j];
}
average = sum / noOfGrades;
return format(average);
}
and call it like this
cout <<" "<<findAverage(i,noOfCourses);