Statistics of an array - c

I need a program to evaluate Min, Max, Avg and Geometric avg of any number of integers. This is what I've come up with so far. Min and Max were working just fine until I added the Avg. Now Min and Avg is working right but Max gives wrong number (usually the second greatest number). Also geometric avg gives only 0.00000. Thanks for your help.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main(int argc, char const *argv[]) {
int arr[100], max, i, min, size, lok = 1;
float arit = 0, geom = 0, sum = 0, prod = 0;
printf("\nSay how many integers you want to input: ");
scanf("%d", &size);
printf("\nType %d integers: ", size);
for (i = 0; i < size; i++) //put values in arr
scanf("%d", &arr[i]);
max = arr[0];
min = arr[0];
for (i = 1; i < size; i++) { //calc maximum
if (arr[i]>max) {
max = arr[i];
lok = i+1;
}
if (arr[i]<min) { //calc minimum
min = arr[i];
lok = i+1;
}
for (i = 0; i < size; i++) { //calc avg
sum = sum + arr[i];
}
arit = sum/size;
for (i = 0; i < size; i++) {
prod = prod * arr[i];
}
geom = pow(prod, 1./size);
}
printf("\n%d is maximum", max);
printf("\n%d is minimum", min);
printf("\n%f is avg", arit);
printf("\n%f is geometric avg", geom);
return 0;
}

The two main problems were
a misplaced closing } brace
wrong intialisation of prod = 0
I have made some other changes too:
check the validity of the inputs
use double instead of float (unless a good reason not to).
remove the unused lok
only one loop is needed for all the statistics
moved the position of the \n newlines as is customary.
This is the amended code:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main(int argc, char const *argv[]) {
int arr[100], max, i, min, size;
double arit = 0, geom = 0, sum = 0, prod = 1; // init prod to 1
printf("\nSay how many integers you want to input: ");
if(scanf("%d", &size) != 1 || size < 1 || size > 100) {
exit(1); // or other action
}
printf("\nType %d integers:\n", size); // added newline
for (i = 0; i < size; i++) {
if(scanf("%d", &arr[i]) != 1) {
exit(1); // or other action
}
}
max = arr[0];
min = arr[0];
for (i = 0; i < size; i++) { // just one loop
if (arr[i] > max) {
max = arr[i];
}
if (arr[i] < min) {
min = arr[i];
}
sum = sum + arr[i];
prod = prod * arr[i];
}
arit = sum / size;
geom = pow(prod, 1.0 / size);
printf("%d is maximum\n", max); // reposition newlines
printf("%d is minimum\n", min);
printf("%f is avg\n", arit);
printf("%f is geometric avg\n", geom);
return 0;
}

This will fix your problem with Min and Max, and I guess also will fix geometric mean(check it) It was a problem closing for sentences
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main(int argc, char const *argv[]) {
int arr[100], max, i, min, size, lok = 1;
float arit = 0, geom = 0, sum = 0, prod = 1;
printf("\nSay how many integers you want to input: ");
scanf("%d", &size);
printf("\nType %d integers: ", size);
for (i = 0; i < size; i++) //put values in arr
scanf("%d", &arr[i]);
max = arr[0];
min = arr[0];
for (i = 1; i < size; i++) { //calc maximum
if (arr[i]>max) {
max = arr[i];
lok = i+1;
}
if (arr[i]<min) { //calc minimum
min = arr[i];
lok = i+1;
}
}
for (i = 0; i < size; i++) { //calc avg
sum = sum + arr[i];
}
arit = sum/size;
for (i = 0; i < size; i++) {
prod = prod * arr[i];
}
geom = pow(prod, 1./size);
printf("\n%d is maximum", max);
printf("\n%d is minimum", min);
printf("\n%f is avg", arit);
printf("\n%f is geometric avg", geom);
return 0;
}
About Geometric mean you are doing this.
float arit = 0, geom = 0, sum = 0, prod = 0;
and then
for (i = 0; i < size; i++) {
prod = prod * arr[i];
}
That allways will return 0 because you initialize prod at 0

Related

why output is 0 here. i am a newbie (20 days experience)

*i want to copy inputed array in sum_of_elements function as argument and then sum all the elements of array, but i am getting output 0.
#include <stdio.h>
int i, num, sum;
int sum_of_elements(int arr[]) {
for (i = 0; i < num; i++) {
for (i = 0; sum = 0, i < num; i++) {
sum += arr[i];
}
return sum;
}
}
int main() {
printf("enter number of digits you want to add\n");
scanf("%d", & num);
int arr[num];
for (i = 0; i < num; i++) {
printf("enter number %d\n", i + 1);
scanf("%d", & arr[i]);
}
int total = sum_of_elements(arr);
printf("%d", total);
return 0;
Look at this line of code:
for (i = 0; sum = 0, i < num; i++) {
This resets sum to 0 every loop.
It should be
for (i = 0, sum = 0; i < num; i++) {
But it's probably better to do this:
sum = 0;
for (i = 0; i < num; i++) {
The issue was with the double for loop in your sum_of_elements function.
Removing the extra for loop, resolves the error.
#include <stdio.h>
int i, num, sum;
int sum_of_elements(int arr[]) {
for (i = 0; i < num; i++) {
sum += arr[i];
}
return sum;
}
int main() {
printf("enter number of digits you want to add\n");
scanf("%d", & num);
int arr[num];
for (i = 0; i < num; i++) {
printf("enter number %d\n", i + 1);
scanf("%d", &arr[i]);
}
int total = sum_of_elements(arr);
printf("%d", total);
return 0;
}

For loop in C langage

I have two functions, one for calculate the min and the max of an array the seconde one is for calculate the average of this array:
void find_min_max(double *tab, int nb, double *pmin, double *pmax) {
double val_min, val_max;
int i;
val_min = tab[0];
val_max = tab[0];
for (i = 0; i < nb; i++) {
if (tab[i] < val_min) {
val_min = tab[i];
} else
if (tab[i] > val_max) {
val_max = tab[i];
}
}
*pmin = val_min;
*pmax = val_max;
}
double find_average(double *tab, int nb) {
double average, sum;
int i;
sum = 0;
for (i = 0; i < nb; i++) {
sum = sum + tab[i];
}
average = sum / nb;
return average;
}
the array that I want to find the min, the max and the average of is a text file that contains floating point numbers:
int main() {
int i, j;
float tab[100] max, min, avg = 0;
FILE *mydata;
FILE *data_res;
f = fopen("data.txt", "r");
new_f = fopen("data_res.txt", "w");
if (mydata == NULL)
printf("Error");
else {
for (i = 0; i < n; i++)
fscanf(mydata, "%f", &tab[i]);
}
for (i = 0; i < 100; i++) {
for (j = i; j < 5; j++) {
fprintf(data_res, "%f ", tab[j]);
avg = find_average(tab);
find_min_max(tab, nb, &min, &max);
}
fprintf(new_f, "MAX = %lf\n", max);
fprintf(new_f, "MIN = %lf\n", min);
}
}
}
But the problem is it does not calculate the correct max and the correct min
There are multiple problems in your code:
n is not defined, the reading loop does not compile
you should test the return value of fscanf() to detect conversion errors and avoid undefined behavior.
you pass the address of float variables to functions that expect double pointers. You should use double for all values.
it is unclear why you use 1196 for the computing loop
it is unclear why you want to compute the average 5 values at a time.
you do not pass the size of the array in avg = find_average(tab);
you always compute the min and max of the first 5 values in find_min_max(tab, 5, &min, &max);
tab_C and b are not defined.
You must explain what you want the code to do with these values. As posted, it is unclear what your intent is from the reading the code.
To compute the running average, min and max, you should modify your code this way:
// compute the average of 5 elements starting at tab[i]
avg = find_average(tab + i, 5);
find_min_max(tab + i, 5, &min, &max);
Here is a modified version:
#include <stdio.h>
void find_min_max(const double *tab, int nb, double *pmin, double *pmax) {
double val_min, val_max;
val_min = val_max = tab[0];
for (int i = 1; i < nb; i++) {
if (tab[i] < val_min) {
val_min = tab[i];
} else
if (tab[i] > val_max) {
val_max = tab[i];
}
}
*pmin = val_min;
*pmax = val_max;
}
double find_average(const double *tab, int nb) {
double sum = 0.0;
for (int i = 0; i < nb; i++) {
sum += tab[i];
}
return sum / nb;
}
int main() {
int i, j;
double tab[1200], tab_C[1200], max, min, avg = 0, H, L, x = 0.2;
FILE *mydata;
FILE *data_res;
file = fopen("data.txt", "r");
data_res = fopen("data_res.txt", "w");
if (mydata == NULL || data_res == NULL) {
fprintf(stderr, "Cannot open files\n");
return 1;
} else {
for (i = 0; i < 1200; i++)
if (fscanf(mydata, "%lf", &tab[i]) != 1) {
fprintf(stderr, "Input error at index %d\n", i);
return 1;
}
}
for (i = 0; i < 1196; i++) {
//this loop is for taking 5 elements by 5
for (j = i; j < i + 5; j++) {
fprintf(data_res, "%f ", tab[j]);
}
fprintf(data_res, "\n");
avg = find_average(tab + i, 5);
find_min_max(tab + i, 5, &min, &max);
L = avg - ((avg - min) * b);
H = avg + ((max - avg) * b);
fprintf(data_res, "MAX = %f\n", max);
fprintf(data_res, "MIN = %f\n", min);
fprintf(data_res, "the average = %f\n", avg);
fprintf(data_res, "low value = %f\n", L);
fprintf(data_res, "High value = %f\n", H);
}
fclose(mydata);
fclose(data_res);
}
}
In find_min_max, try using this:
if (tab[i] > val_max)
{
val_max = tab[i];
}
instead of
else if (tab[i] > val_max)
{
val_max = tab[i];
}

how can i replace scanf with for loop counter?

I am writing a program in order to count all achilles numbers without the math.h library. In this programm first I calculate powerful numbers after that I calculate GCD of powerful number. If GCD is 1 then the current number is achilles.
My problem is that my program works with scanf() but not with for loop counter! What i am doing wrong?
Thank you very much!
#include <stdio.h>
#define MAX 1000
int main(void)
{
int n;
int i, j, a;
int counter2 = 0;
int large;
int small;
int rem, gcd, max = 1, min = 1;
int achilles;
for (a = 1; a <= MAX; a++) //for loop for counter
{
n=a;
for (i = 1; i <= n; i++)
{
int count = 0;
for (j = 1; j <= i; j++)
{
if (i % j == 0)
{
count++;
}
}
int l = 0;
if (count == 2)
{
while (n % i == 0) // calculate factor and his exponent
{
l++;
n = n / i;
}
if (l > max) // calculates min and max in order to find GCD
{
max = l;
}
if (l < min)
{
min = l;
}
}
large = max;
small = min;
while (small) { // While small is not 0
// Calculates GCD
rem = large % small;
large = small;
small = rem;
}
gcd = large;
// printf("GCD(%d,%d)= %d", large, small, gcd);
}
if (gcd == 1) {
achilles = n;
// printf("%d\n", achilles);
}
// printf("GCD(%d,%d)= %d", max, min, gcd);
printf("%d\n", achilles);
}
}
The programm before editing with the for loop is the following!
#include <stdio.h>
#define MAX 1000
int main(void)
{
int n;
int i, j, a;
int counter2 = 0;
int large;
int small;
int rem, gcd, max = 1, min = 1;
int achilles;
scanf("%d", &n);
printf("%d = ",n);
for (i = 1; i <= n; i++)
{
int count = 0;
for (j = 1; j <= i; j++)
{
if (i % j == 0)
{
count++;
}
}
int l = 0;
if (count == 2)
{
while (n % i == 0) // calculate factor and his exponent
{
l++;
n = n / i;
}
if (l > max) // calculates min and max in order to find GCD
{
max = l;
}
if (l < min)
{
min = l;
}
}
large = max;
small = min;
while (small) { // While small is not 0
// Calculates GCD
rem = large % small;
large = small;
small = rem;
}
gcd = large;
// printf("GCD(%d,%d)= %d", large, small, gcd);
}
/*if (gcd == 1) {
achilles = n;
// printf("%d\n", achilles);
}*/
printf("GCD(%d,%d)= %d", max, min, gcd);
//printf("%d\n", achilles);
}

Generate random numbers in array and count the average, max, min, sum

This code is supposed to generate 30 random numbers, 0-100, and print the average, max value, and the min value. But it has logical errors and I cant help but think I've made a stupid mistake.
****code is supposed to generate 30 numbers from 0-100, and display mean, max, and min****
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define SIZE 30
int generateRandom(void);
int main(void)
{
int points[SIZE], i, sum, max, min, num;
double average;
srand(time(NULL)); /*Seed random number generator*/
num = generateRandom(); /*Genrate the random numbers*/
printf("num = %d\n", num); /*Print the random numbers*/
sum = 0;
for ( i = 0; i < SIZE; i++) /*Find the average*/
{
sum += points[i];
average = sum / SIZE;
}
printf("Average = %f", average); /*Print the average*/
max = points[0]; /*initialize the max to 0*/
for ( i = 0; i < SIZE; i++) /*find the min*/
{
if (points[i] > max)
{
max = points[i];
}
}
printf("Maximum = %d\n", max); /*print the maximum number*/
min = points[0]; /*initialize the min*/
for ( i = 0; i < SIZE; i++) /*Find the min*/
{
if (points[i] < min)
{
min = points[i];
}
}
printf("Minimum = %d\n", min); /*Print the minimum number*/
return 0;
}
int generateRandom(void)
{
int random;
random = rand() % 101;
return random;
}
You generate just one random number, which you store in num. Then your code behaves as if it had 30 random numbers stored in points. But it never makes this happen.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define SIZE 30
int generateRandom(void);
int main(void)
{
int points[SIZE],i,sum,max,min,num;
double average;
srand(time(NULL));
for(i = 0; i < SIZE; i++){
points[i] = generateRandom();
}
sum = 0;
for(i = 0; i < SIZE; i++)
{
sum += points[i];
}
average = (sum * 1.0) / SIZE; /*you need double here*/
printf("Average = %f\n",average);
max = points[0];
for(i = 1; i < SIZE; i++)
{
if(points[i] > max)
{
max = points[i];
}
}
printf("Maximum = %d\n",max);
min = points[0];
for(i = 1; i < SIZE; i++)
{
if(points[i] < min)
{
min = points[i];
}
}
printf("Minimum = %d\n",min);
return 0;
}
int generateRandom(void)
{
int random;
random = rand() % 101;
return random;
}

Finding Max value and Average Of All elemements in 2D array in C

EDIT II
I'm finally getting somewhere, now i get my random values with a return from the maxavg() function.
My only question now is, when i run the program i always get:
average: 0
maximum: 33
why? it does not make much sense.
Here is the new code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <limits.h>
int GetRand(int min, int max);
struct maxavg;
int main ()
{
int a[21][21], i , j, average, maximum, ret;
for (i = 0; i < 21; i++)
{
for ( j = 0; j < 21; j++)
{
a[i][j] = GetRand(0, 100);
printf("%3d" , a[i][j]);
}
a[2][15] = -1;
a[10][6] = -1;
a[13][5] = -1;
a[15][17] = -1;
a[17][17] = -1;
a[19][6] = -1;
printf("\n");
}
printf("average = %d \n maximum = %d", average, maximum);
return 0;
}
// random seed
int GetRand(int min, int max);
int get ()
{
int i, r;
for (i = 0; i < 21; i++)
{
r = GetRand(0, 100);
printf("Your number is %d \n", r);
}
return(0);
}
int GetRand(int min, int max)
{
static int Init = 0;
int rc;
if (Init == 0)
{
srand(time(NULL));
Init = 1;
}
rc = (rand() % (max - min +1) +min);
return (rc);
}
struct pair
{
int max;
int avg;
};
// max and average
struct pair maxavg()
{
struct pair p;
int max=INT_MIN, sum=0, count=0, avg, i, j, current;
for(i = 0; i < 21; i++){
for(j =0; j < 21; j++){
if(current > -1){
sum = sum + current;
count = count + 1
;if(current > max){
max = current;
}
}
}
}
avg = sum/count;
printf("Max is %d \n", max);
printf("Average is %d \n", avg);
p.max = max;
p.avg = avg;
return p;
}
EDIT:
So here is what i'm doing, i get error messages:
Average:
// Average Code
value = a[i][j];
int actualvalue, suma = 0, quant;
for(i=0; i<21; i++){
for(j=0; j<21; j++){
if (actualvalue > -1){
a[i][j] = actualvalue;
suma = suma + actualvalue;
// sum actual value + nextvalue (sum of all > -1) //
}
else if {
quant = quant + 1;
//(sum the quantity of times a value has been greater than -1)//
}
}
}
printf("The average value is:", suma/quant); ///(sun of all values > -1)/(sum of quantity value was > -1)/
Find Maximum:
// Max
int variableP = a[0][0];
value = a[i][j];
int variableP = a[i][j]
for(i=0; i<21; i++){
for(j=0; j<21; j++){
if(variableP < newvalue){
variableP = newvalue
}
}
}
printf("The max value of the 2D array is", %d);
Average and Maximum:
// max and average
int maxvg();
int max=INT_MIN, sum=0, count=0, avg;
for(i = 0; i < 21; i++){
for(j =0; j < 21; j++){
if(current > -1){
sum = sum + current;
count = count + 1
if(current > max){
max = current;
}
}
}
}
avg = sum/count;
printf("Max is %d \n", max);
printf("Average is %d \n", avg);
So how right or wrong is this? what am i missing.
i mostly get:
[Error] expected '=', ',', ';', 'asm' or '__attribute__' before '<' token
[Warning] data definition has no type or storage class
[Error] initializer element is not constant
[Error] expected declaration specifiers or '...' before string constant
Am i at least close to it?
Thanks in advance.
END OF EDIT
I created a 2D array with random numbers from 0 to 100 (and a couple of -1) values with this code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main ()
{
int a[21][21], i, j;
for (i = 0; i < 21; i++) {
for (j = 0; j < 21; j++) {
a[i][j] = GetRand (0, 100);
a[7][15] = -1;
a[10][6] = -1;
a[13][5] = -1;
a[15][17] = -1;
a[17][17] = -1;
a[19][6] = -1;
printf ("%3d", a[i][j]);
}
printf ("\n");
}
return 0;
}
// random seed
int GetRand (int min, int max);
int get ()
{
int i, r;
for (i = 0; i < 21; i++) {
r = GetRand (0, 100);
printf ("Your number is %d \n", r);
}
return (0);
}
int GetRand (int min, int max)
{
static int Init = 0;
int rc;
if (Init == 0) {
srand (time (NULL));
Init = 1;
}
rc = (rand () % (max - min + 1) + min);
return (rc);
}
This prints the array created. Now I want to calculate the maximum value of all values inside the array and the total average of all values in the array, all while ignoring all -1 values, so only from 0 to 100. Since I'm a total beginner I'm having problems creating these functions. So here are my ideas.
//For the average
for(i=0; i<1; i++){
for(j=0; j<21; j++){
if (actualvalue > -1){
//sum actualvalue + nextvalue (sum of all the values greater than -1)//
}
else if (actualvalue > -1){
//(sum the quantity of times a value has been greater than -1)//
}
}
}
}
printf("The average value is", //(sum of all values>-1)/(sum of quantity value was >-1) //);
I'm representing the thing i don't know how to write in code in words so you get my idea.
Now for finding the maximum: what i think i should do is initialize the array and make a variable adopt the first value it finds that's > -1, then rewind and initialize again, if the actualvalue < newvalue then make variableP adopt the newvalue:
//max
int variableP = a[i][j]
for(i=0; i<21; i++){
for(j=0;j<21;j++){
if(variableP < newvalue){
variableP = newvalue
}
printf("The max value of the 2D array is", %d);
}
I know it's evident i'm not sure what i'm writing here, but i think my idea of it is correct, i hope i'm explaining it well enough.
Sum is as you say.
Average requires you count number of >-1 values.
Max looks right lines. Finish off your ideas and ask again if it doesn't work
You can do both max and avg in one loop.
Declare three variables: max=-999999, sum=0, count=0.
Each time when current cell is not -1 increase sum by it's value and count by 1.
Each time check if current value is bigger than max, then set max to current value.
After the loop is done, avg = sum/count.
Consider you are doing all your arithmetic using integers, and integer division is integer. Perhaps you have better to do a double result with:
/* you don't actually need to cast to double in both operators, as the
* one not casted will be automagically casted to double to operate on.
*/
double average = (double) sum_of_samples / (double) number_of_samples;
You have to cast at least one of the operators, because if you don't you'll get the result as before (a 0 integer result) converted to double to assign to the variable.

Resources