Function to find average for array - c

Did I implement float overallavg(float* matrix, int rows, int cols)correctly? I think I didn't. I'm trying to return the average value of the elements of the array pointed to by matrix. Should I call the other two functions into the overall one and then divide by the total number elements in the array?
#include <stdio.h>
#include <stdlib.h>
float *readMatrix(int rows, int cols);
float *rowavg(float *matrix, int rows, int cols);
float *colavg(float *matrix, int rows, int cols);
float overallavg(float* matrix, int rows, int cols);
void printavg(float *matrix, float *rowAve, float *colAve, float overallAve, int rows, int cols);
#define MAX_DIM 10
int main(void)
{
int done = 0;
int rows, cols;
float *dataMatrix;
float *rowAveVector;
float *colAveVector;
float overallAve;
while (!done)
{
// Prompt user to enter row and column dimensions of matrix (must be > 0)
do
{
printf("Enter row dimension (must be between 1 and %d): ", MAX_DIM);
scanf("%d", &rows);
} while(rows <= 0 || rows > MAX_DIM);
do
{
printf("Enter column dimension (must be between 1 and %d): ", MAX_DIM);
scanf("%d", &cols);
} while(cols <= 0 || cols > MAX_DIM);
dataMatrix = readMatrix(rows, cols);
if (dataMatrix == NULL)
{
printf ("Program terminated due to dynamic memory allocation failure\n");
return (0);
}
rowAveVector = rowAverage(dataMatrix, rows, cols);
colAveVector = colAverage(dataMatrix, rows, cols);
if(rowAveVector == NULL || colAveVector == NULL)
{
printf("malloc failed. Terminating program\n");
return (0);
}
overallAve = overallAverage(dataMatrix, rows, cols);
//Print Averages
printAverages(dataMatrix, rowAveVector, colAveVector, overallAve, rows, cols);
free(dataMatrix);
free(rowAveVector);
free(colAveVector);
//Check if user wants to enter a new matrix
printf("Enter 0 to continue with a new matrix\n");
printf("Enter any other number to terminate the program: ");
scanf("%d", &done);
}
//That's it, we are done
return (0);
}
float *readMatrix(int rows, int cols)
{
int i=0;
int j=0;
int elements=0;
float *m=malloc(rows*cols*sizeof(float));
if (m==NULL)
{
printf("error\n");
return NULL;
}
printf("Enter values for the matrix: ");
for (i=0;i<rows;i++)
{
for (j=0;j<cols;j++)
{
elements = i*cols+j;
scanf("%f", &m[elements]);
}
}
return m;
}
float *readMatrix(int rows, int cols)
{
int i=0;
int j=0;
int elements=0;
float *m=malloc(rows*cols*sizeof(float));
if (m==NULL)
{
printf("error\n");
return NULL;
}
printf("Enter values for the matrix: ");
for (i=0;i<rows;i++)
{
for (j=0;j<cols;j++)
{
elements = i*cols+j;
scanf("%f", &m[elements]);
}
}
return m;
}
float *rowavg(float *matrix, int rows, int cols)
{
if (matrix==NULL)
{
return NULL;
}
int i=0;
int j=0;
float mean=0;
float *Average_array=malloc(rows*sizeof(float));
if (Average_array==NULL)
{
return NULL;
}
for (i=0;i<rows;i++)
{
for (j=0;j<cols;j++)
{
mean+=matrix[i*cols+j];
}
Average_array[i]=(float)(mean/cols);
}
return Average_array;
}
float *colavg(float *matrix, int rows, int cols)
{
if (matrix==NULL)
{
return NULL;
}
int i=0;
int j=0;
float mean=0;
float *Average_array=malloc(cols*sizeof(float));
if (Average_array==NULL)
{
return NULL;
}
for (i=0;i<cols;i++)
{
for (j=0;j<rows;j++)
{
mean+=matrix[j*cols+i];
}
Average_array[i]=(float)(mean/rows);
}
return Average_array;
}
float overallavg(float* matrix, int rows, int cols)
{
if (matrix==NULL)
{
return NULL;
}
int i=0;
int j=0;
float mean_1=0;
float mean_2=0;
float avg=0;
float elements=0;
float sum=0;
elements=rows*cols;
for (i=0;i<rows;i++)
{
for (j=0;j<cols;j++)
{
mean_1+=matrix[i*rows+j];
}
}
for (i=0;i<cols;i++)
{
for (j=0;j<rows;j++)
{
mean_2+=matrix[j*cols+i];
}
}
sum=mean_1+mean_2;
avg=sum/elements-1;
}

the following code:
cleanly compiles
contains the needed #include statements
Note: this line:
avg=sum/elements-1;
will not calculate the average of all the elements but rather a somewhat larger value because the total number of elements is being decremented by 1
Suggestion, in the function: overallavg() do not calculate separate 'mean' values, rather simply step through the whole array summing each element, then divide by the total number of elements
Suggestion, use an indent width of 4 spaces, as that is easily visible, even with a variable width font. 2 spaces with a variable width font just looks like the indented row is indented about 1/2 the width of a char. I.E. barely visible and very messy looking. (code is read many many times so should be written to be very easy to read.
#include <stdio.h> // printf() scanf()
#include <stdlib.h> // malloc, free()
float *readMatrix( size_t rows, size_t cols)
{
//int i=0;
//int j=0;
size_t elements=0;
float *m=malloc(rows*cols*sizeof(float));
if (m==NULL)
{
printf("error\n");
return NULL;
}
printf("Enter values for the matrix: ");
for (size_t i=0; i<rows; i++)
{
for ( size_t j=0; j<cols; j++)
{
elements = i*cols+j;
scanf("%f", &m[elements]);
}
}
return m;
}
float *rowavg(float *matrix, size_t rows, size_t cols)
{
if (matrix==NULL)
{
return NULL;
}
//int i=0;
//int j=0;
float mean=0;
float *Average_array=malloc(rows*sizeof(float));
if (Average_array==NULL)
{
return NULL;
}
for ( size_t i=0; i<rows; i++)
{
for ( size_t j=0; j<cols; j++)
{
mean+=matrix[i*cols+j];
}
Average_array[i] = (mean/(float)cols);
}
return Average_array;
}
float *colavg(float *matrix, size_t rows, size_t cols)
{
if (matrix==NULL)
{
return NULL;
}
//int i=0;
//int j=0;
float mean=0;
float *Average_array = malloc( cols*sizeof(float) );
if (Average_array==NULL)
{
return NULL;
}
for ( size_t i=0; i<cols; i++)
{
for (size_t j=0; j<rows; j++)
{
mean+=matrix[j*cols+i];
}
Average_array[i] = (mean/(float)rows);
}
return Average_array;
}
float overallavg(float* matrix, size_t rows, size_t cols)
{
#if 0
if (matrix==NULL)
{
return NULL;
}
#endif
//int i=0;
//int j=0;
float mean_1=0;
float mean_2=0;
float avg=0;
float elements=0;
float sum=0;
elements= (float)rows* (float)cols;
for ( size_t i=0;i<rows;i++)
{
for ( size_t j=0;j<cols;j++)
{
mean_1+=matrix[i*rows+j];
}
}
for ( size_t i=0; i<cols; i++)
{
for ( size_t j=0; j<rows ;j++)
{
mean_2+=matrix[j*cols+i];
}
}
sum=mean_1+mean_2;
avg=sum/elements-1;
return avg;
}

Related

Function inputElements() taking input only once

I am trying to create a program to find the transpose of a matrix my dynamic memory allocation. However, while entering the elements of the matrix I can't input more than one element, its only taking the a[0][0] as the input and the program is ending after that.
#include <stdio.h>
#include <stdlib.h>
void createMatrix(int **, int, int);
void inputElements(int **, int, int);
void transpose(int **, int **, int, int);
void display(int **, int, int);
void main()
{
int **matrix, **trans, rows, cols;
printf("\nEnter number of rows in the matrix: ");
scanf("%d", &rows);
printf("\nEnter number of columns in the matrix: ");
scanf("%d", &cols);
createMatrix(matrix, rows, cols);
createMatrix(trans, cols, rows);
inputElements(matrix, rows, cols);
transpose(matrix, trans, rows, cols);
printf("\nMATRIX:\n");
display(matrix, rows, cols);
printf("\nTRANSPOSE OF THE MATRIX:\n");
display(trans, rows, cols);
}
void createMatrix(int **a, int r, int c) //for allocating memory for the matrix
{
int i, j;
a = (int **)malloc(sizeof(int *) * r);
for(i = 0; i < r; i++)
a[i] = (int *)malloc(sizeof(int) * c);
}
void inputElements(int **a, int r, int c) //for entering matrix elements
{
int i, j, t;
for(i = 0; i < r; i++)
{
for(j = 0; j < c; j++)
{
printf("\nEnter matrix element[%d][%d]: ", i + 1, j + 1);
fflush(stdin);
getchar();
scanf("%d", &(a[i][j]));
}
}
}
void transpose(int **a, int **t, int r, int c) //for finding out the transpose of the matrix
{
int i, j;
for (i = 0; i < c; i++)
{
for (j = 0; j < r; j++)
t[i][j] = a[j][i];
}
}
void display(int **a, int r, int c) //for displaying the matrix
{
int i, j;
for (i = 0; i < r; i++)
{
printf("\n");
for (j = 0; j < c; j++)
printf("\t%d", a[i][j]);
}
}
There are many posts about scanf in loops I've seen, but I wasn't able to connect my issue with any of them.

Cannot modify a matrix element's value with a function

i'm trying to create a function that sets to 0 the value of every matrix element a[i][j] which is divisible by both i and j. I tried to do it this way but the program just "exits" without giving any error or warning after the matrix=editMat(matrix, nrows, ncols); line.
#include <stdio.h>
#include <stdlib.h>
FILE *openFileR(const char *);
int rows(FILE *);
int cols(FILE *);
int **readMat(FILE *, int **);
int **allocMat(int, int);
void printMat(int **, int, int);
int **editMat(int, int, int**);
int main()
{
FILE *fp, *fpout;
fp=openFileR("matrixmag.txt");
int nrows=rows(fp); int ncols=cols(fp);
int **matrix=allocMat(nrows, ncols);
readMat(fp, matrix);
printMat(matrix, nrows, ncols);
matrix=editMat(nrows, ncols, matrix);
printMat(matrix, nrows, ncols);
return 0;
}
int **editMat(int nrows, int ncols, int **matrix )
{
int i, j;
for(i=0; i<nrows; i++)
{
for(j=0; j<ncols; j++)
{
if((matrix[i][j])%i==0 && (matrix[i][j])%j==0)
{
matrix[i][j]=0;
}
}
}
return matrix;
}
int **readMat(FILE *fp, int **matrix)
{
int value, row, col;
while(fscanf(fp, "%d %d %d", &value, &row, &col)!=EOF)
{
matrix[row][col]=value;
}
return matrix;
}
int **allocMat(int nrows, int ncols)
{
int **matrix=malloc(nrows*(sizeof(int *)));
for(int i=0; i<nrows; i++)
{
matrix[i]=malloc(ncols*sizeof(int));
}
return matrix;
}
void printMat(int **matrix, int nrows, int ncols)
{
for(int i=0; i<nrows; i++)
{
for(int j=0; j<ncols; j++)
{
printf("%d ", matrix[i][j]);
}
printf("\n");
}
}
int cols(FILE *fp)
{
int columns;
fscanf(fp, "%d", &columns);
printf("Columns:%d\n", columns);
return columns;
}
int rows(FILE *fp)
{
int lines;
fscanf(fp,"%d", &lines);
printf("Rows:%d\n", lines);
return lines;
}
FILE *openFileR(const char *nome_file)
{
FILE *fp;
printf("File name: %s\n", nome_file);
fp=fopen(nome_file, "r");
if(fp==NULL)
{
printf("Couldn't open file\n");
exit(-1);
}
else
printf("File correctly opened\n");
return fp;
}
Input file is
3 3
2 0 0
7 0 1
6 0 2
9 1 0
5 1 1
1 1 2
4 2 0
3 2 1
8 2 2
sorry about the errors, i didn't check what i wrote before
Just figured out i was trying to divide a number by 0, since i and j were both initialized to 0
int **editMat(int nrows, int ncols, int **matrix )
{
int i, j;
for(i=0; i<nrows; i++)
{
for(j=0; j<ncols; j++)
{
if((matrix[i][j])%i==0 && (matrix[i][j])%j==0)
{
matrix[i][j]=0;
}
}
}
return matrix;
}
This way it works fine
int **editMat(int nrows, int ncols, int **matrix )
{
int i, j;
for(i=1; i<nrows; i++)
{
for(j=1; j<ncols; j++)
{
if((matrix[i][j])%i==0 && (matrix[i][j])%j==0)
{
matrix[i][j]=0;
}
}
}
return matrix;
}
Thanks everybody for the help anyway :)

Function to Print Out Averages

I'm trying to print out the averages in the function void printavg(float *matrix,float *rowAve,float *colAve, float overallAve, int rows, int cols);
but when I tried to do a test run on printing out the average for rows I didn't get the right answer. What's the proper way to print out the avg using the printavg function. Here's an example of what the program should do:
Enter row dimension <must be between 1 and 5>: 3
Enter column dimension <must be between 1 and 5>: 2
Enter 6 data values for 3 x 2 matrix, in by-row order
1
2
3
4
5
6
1.00 2.00 1.50
3.00 4.00 3.50
5.00 6.00 5.50
3.00 4.00
Overall average is: 3.500000
Enter 0 to continue with a new matrix
Enter any other number to terminate the program:
Here's the code that I have so far
#include <stdio.h>
#include <stdlib.h>
// Function Prototypes
float *readMatrix(int rows, int cols);
float *rowavg(float *matrix, int rows, int cols);
float *colavg(float *matrix, int rows, int cols);
float overallavg(float* matrix, int rows, int cols);
void printavg(float *matrix, float *rowAve, float *colAve, float overallAve, int rows, int cols);
#define MAX_DIM 15
int main(void)
{
int done = 0;
int rows, cols;
float *dataMatrix;
float *rowAveVector;
float *colAveVector;
float overallAve;
while (!done)
{
// Prompt user to enter row and column dimensions of matrix (must be > 0)
do
{
printf("Enter row dimension (must be between 1 and %d): ", MAX_DIM);
scanf("%d", &rows);
} while(rows <= 0 || rows > MAX_DIM);
do
{
printf("Enter column dimension (must be between 1 and %d): ", MAX_DIM);
scanf("%d", &cols);
} while(cols <= 0 || cols > MAX_DIM);
dataMatrix = readMatrix(rows, cols);
if (dataMatrix == NULL)
{
printf ("Program terminated due to dynamic memory allocation failure\n");
return (0);
}
rowAveVector = rowavg(dataMatrix, rows, cols);
colAveVector = colavg(dataMatrix, rows, cols);
if(rowAveVector == NULL || colAveVector == NULL)
{
printf("malloc failed. Terminating program\n");
return (0);
}
overallAve = overallavg(dataMatrix, rows, cols);
//Print Averages
printAverages(dataMatrix, rowAveVector, colAveVector, overallAve, rows, cols);
free(dataMatrix);
free(rowAveVector);
free(colAveVector);
//Check if user wants to enter a new matrix
printf("Enter 0 to continue with a new matrix\n");
printf("Enter any other number to terminate the program: ");
scanf("%d", &done);
}
//That's it, we are done
return (0);
}
float *readMatrix(int rows, int cols)
{
int i=0;
int j=0;
int elements=0;
float *m=malloc(rows*cols*sizeof(float));
if (m==NULL)
{
printf("error\n");
return NULL;
}
printf("Enter values for the matrix: ");
for (i=0;i<rows;i++)
{
for (j=0;j<cols;j++)
{
elements = i*cols+j;
scanf("%f", &m[elements]);
}
}
return m;
}
float *rowavg(float *matrix, int rows, int cols)
{
if (matrix==NULL)
{
return NULL;
}
int i=0;
int j=0;
float mean=0;
float *Average_array=malloc(rows*sizeof(float));
if (Average_array==NULL)
{
return NULL;
}
for (i=0;i<rows;i++)
{
for (j=0;j<cols;j++)
{
mean+=matrix[i*cols+j];
}
Average_array[i]=(float)(mean/cols);
}
return Average_array;
}
float *colavg(float *matrix, int rows, int cols)
{
if (matrix==NULL)
{
return NULL;
}
int i=0;
int j=0;
float mean=0;
float *Average_array=malloc(cols*sizeof(float));
if (Average_array==NULL)
{
return NULL;
}
for (i=0;i<cols;i++)
{
for (j=0;j<rows;j++)
{
mean+=matrix[j*cols+i];
}
Average_array[i]=(float)(mean/rows);
}
return Average_array;
}
float overallavg(float* matrix, int rows, int cols)
{
float sum=0;
int i=0;
float elements=0;
float mean;
elements=rows*cols;
for (i=0;i<elements;i++)
{
sum+=matrix[i];
}
mean=sum/elements;
return mean;
}
void printavg(float *matrix, float *rowAve, float *colAve, float overallAve, int rows, int cols)
{
printf("%f",rowAve[rows,cols]);
}

Dynamic allocation and Arrays

My question is regrading the second function
float *rowavg(float *matrix,int rows,int cols)
So i'm suppose to dynamically allocate an array of floats with row elements and return NULL if allocation fails. I think i did this right, right? The other part that i'm trying to do is set the ith element of the new array to the average of the values in the ith row of the previous array. This part is where I'm getting got up. Did i call the previous array correctly(I believe no)?
#include <stdio.h>
#include <stdlib.h>
float *readMatrix(int rows, int cols);
float *rowavg(float *matrix, int rows, int cols);
float *colavg(float *matrix, int rows, int cols);
#define MAX_DIM 10
int main(void)
{
int done = 0;
int rows, cols;
float *dataMatrix;
float *rowAveVector;
float *colAveVector;
float overallAve;
while (!done)
{
do
{
printf("Enter row dimension (must be between 1 and %d): ", MAX_DIM);
scanf("%d", &rows);
} while(rows <= 0 || rows > MAX_DIM);
do
{
printf("Enter column dimension (must be between 1 and %d): ", MAX_DIM);
scanf("%d", &cols);
} while(cols <= 0 || cols > MAX_DIM);
dataMatrix = readMatrix(rows, cols);
if (dataMatrix == NULL)
{
printf ("Program terminated due to dynamic memory allocation failure\n");
return (0);
}
rowAveVector = rowAverage(dataMatrix, rows, cols);
colAveVector = colAverage(dataMatrix, rows, cols);
if(rowAveVector == NULL || colAveVector == NULL)
{
printf("malloc failed. Terminating program\n");
return (0);
}
}
float *readMatrix(int rows, int cols)
//Dynamically allocate an array to hold a matrix of floats.
//The dimension of the matrix is numRows x numCols.
//If the malloc fails, return NULL.
//Otherwise, prompt the user to enter numRows*numCols values
//for the matrix in by-row order.
//Store the values entered by the user into the array and
//return a pointer to the array.
{
int i=0;
int j=0;
int elements=0;
float *m=malloc(rows*cols*sizeof(float));
if (m==NULL)
{
printf("error\n");
return NULL;
}
printf("Enter values for the matrix: ");
for (i=0;i<rows;i++)
{
for (j=0;j<cols;j++)
{
elements = i*cols+j;
scanf("%f", &m[elements]);
}
}
return m;
}
float *rowavg(float *matrix, int rows, int cols)
{
int i=0;
float mean=0;
float *mat=malloc(rows*sizeof(float));
if(mat==NULL)
{
printf("error\n");
return NULL;
}
for (i=0;i<rows;i++)
{
readMatrix(rows,cols);
mean=
mat[i]=mean;
}
}
First of all, call of readMatrix(rows,cols); not needed in rowavg.
And if you want rowavg to return average values for each row in your matrix, try the following:
float *rowavg(float *matrix, int rows, int cols)
{
// check matrix befor use
if (matrix == NULL)
{
return NULL;
}
int i=0;
int j=0;
double mean; // variable name from original code in the question
float *avgarr = (float *)malloc(rows*sizeof(float));
if(avgarr == NULL)
{
return NULL;
}
for (i=0;i<rows;i++)
{
mean = 0.0;
for (j=0;j<cols;j++)
{
mean += matrix[i*cols+j];
}
avgarr[i] = (float)(mean/cols);
}
return avgarr;
}
And because in main you already have
rowAveVector = rowAverage(dataMatrix, rows, cols);
if(rowAveVector == NULL)
{
printf("malloc failed. Terminating program\n");
return (0); // here consider return value different from 0
}
you should not use printf("error\n"); in rowavg.
And think over using free after allocatied memory not needed any more.

I want that vector_total dont have any repeated number

I need that vector_total dont have any repeated number.
Function for entry vector1 and vector2 that are declared in main().
void entrada_vectors(int vector1[], int vector2[], int vector_total[], int *n, int *m)
{
int i=0, j=0;
/*Entrarem els nombres del vector 1 primer */
for (i=0; i<*n; i++)
{
vector_total[i]=vector1[i];
}
/*Entrarem els nombres del vector 2 després */
for (i=*n; i<*n+*m; i++)
{
if (j<*m)
{
vector_total[i]=vector2[j];
j++;
}
}
}
Function 2. This is for order numbers in vector_total.
void ordena(int vector_total[], int *n, int *m)
{
int i=0, j=0;
int aux=0;
for (i=0; i<*n+*m-1; i++)
{
for (j=0; j<*n+*m-1; j++)
{
if (vector_total[j]>vector_total[j+1])
{
aux=vector_total[j];
vector_total[j]=vector_total[j+1];
vector_total[j+1]=aux;
aux=0;
}
}
}
}
Function 3. Print vector_total
void mostra(int vector_total[], int *n, int *m )
{ int i;
for (i=0; i<*n+*m; i++)
{
printf ("Pos %d del vector: %d\n", i, vector_total[i] );
}
}
Function 4. Here are the problem!! This function is for clean my vector_total and drop the repeated numbers.
void limpiar_repetidos(int vector_total[], int *n, int *m)
{
int x=0, i=0, j=0;
for (i=0; i<*n+*m-1; i++)
{
for (j=0; j<*n+*m-1; j++)
{
if (vector_total[j]==vector_total[j+1])
{
x=j+1;
for (i=*n+*m; i>x; i--)
{
vector_total[i-1]=vector_total[i];
}
}
}
}
}
And here is my main. And my declaration variables:
int vector1[]={7,1,5,3,4,2};
int vector2[]={3,7,3,0,9,10};
int n=sizeof(vector1)/sizeof(vector1[0]);
int m=sizeof(vector2)/sizeof(vector2[0]);
int vector_total[n+m];
main()
{
entrada_vectors(vector1, vector2, vector_total, &n, &m);
ordena(vector_total, &n, &m);
mostra(vector_total, &n, &m);
limpiar_repetidos(vector_total, &n, &m);
printf ("==================\n");
mostra(vector_total, &n, &m);
return 0;
}
Thanks everybody! :)
1) If function deal with only a vector_total , Length of the vector_total is better to pass by one argument. Also you do not need to pointer pass if it will not change.
void mostra(int vector_total[], int len){
int i;
for (i=0; i<len; i++) {
printf ("Pos %d del vector: %d\n", i, vector_total[i] );
}
}
2) function need a new length after the element has been removed. Also, deletion of adjacent same elements that can be like this.
int limpiar_repetidos(int vector_total[], int len){//int *n, int *m --> int len
int i, size, new_size;
size = len;
for(i = new_size = 1; i < size; ++i){
if(vector_total[new_size-1] != vector_total[i])
vector_total[new_size++] = vector_total[i];
}
return new_size;
}
Example of use
mostra(vector_total, m + n);
int l = limpiar_repetidos(vector_total, n + m);
mostra(vector_total, l);

Resources