I have written a C program in which I output the lowest and highest temperature with day of the week and time in the lower function. However, sometimes values are duplicated. How can I implement this in my function so that both times are displayed?
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <limits.h>
double week_statistics(double array[52][7][24], int kalenderwoche, int j, int i, int k, int daymin, int hourmin, int daymax, int hourmax){
double min = array[0][0][0];
for(j = 0; j < 7; j ){
for(k = 0; k < 24; k ){
if(array[i][j][k] < min){
min = array[i][j][k];
daymin = j 1;
hourmin = k 1;
}}}
printf("Die niedrigste Temperatur war %lf° in der %d. Kalenderwoche am %d. Wochentag um %d Uhr.\n", min, kalenderwoche, daymin, hourmin);
double max = array[0][0][0];
for(i = 0; i < 52; i ){
for(j = 0; j < 7; j ){
for(k = 0; k < 24; k ){
if(array[i][j][k] > max){
max = array[i][j][k];
daymax = j 1;
hourmax = k 1;
}}}}
printf("Die höchste Temperatur war %lf° in der %d. Kalenderwoche am %d. Wochentag um %d Uhr.\n", max, kalenderwoche, daymax, hourmax);
}
int main(){
double array[52][7][24] = {{
{9.6, 9.4, 9.3, 9.1, 7.9, 7.7, 7.3, 7.2, 8.8, 9.3, 9.7, 9.4, 10.2, 9.7, 9.9, 9.5, 9.2, 9.3, 9.2, 7.1, 6.1, 5.9, 5.6, 5.2},
{4.9, 4.6, 4.6, 4.1, 3.5, 3.1, 2.6, 2.6, 3.5, 5.1, 6.2, 8.3, 9.0, 9.3, 9.1, 8.0, 6.8, 6.4, 5.4, 5.2, 4.8, 4.5, 5.0, 5.5},
{6.3, 6.8, 7.0, 7.2, 7.1, 7.2, 7.1, 7.4, 7.7, 8.2, 8.7, 9.1, 8.8, 8.7, 8.6, 8.4, 8.0, 7.9, 7.7, 7.6, 7.5, 7.3, 7.3, 7.2},
{7.1, 7.0, 6.9, 6.8, 6.7, 6.7, 6.7, 6.6, 6.7, 6.8, 6.9, 7.2, 7.5, 7.7, 8.1, 8.3, 8.0, 7.7, 8.1, 8.2, 7.7, 7.5, 7.7, 7.9},
{8.1, 8.0, 7.9, 7.8, 7.5, 7.2, 6.9, 7.2, 8.0, 8.4, 8.7, 9.0, 8.7, 8.9, 9.0, 7.8, 8.5, 8.1, 7.7, 7.7, 6.7, 7.0, 6.5, 7.1},
{6.4, 6.6, 6.3, 5.8, 5.0, 4.9, 4.7, 4.6, 4.9, 5.3, 6.1, 5.5, 5.3, 5.7, 5.8, 6.5, 6.6, 5.8, 5.8, 7.1, 7.0, 7.0, 6.3, 5.8},
{4.4, 4.0, 3.8, 3.8, 4.2, 4.2, 4.3, 3.8, 4.4, 5.2, 5.7, 5.9, 6.1, 6.7, 6.3, 5.9, 5.5, 5.1, 5.0, 5.0, 5.2, 5.7, 7.2, 7.7}
}};
int kalenderwoche = 45;
int i, j,k;
int daymin,daymax = 1;
int hourmin,hourmax = 1;
week_statistics(array, kalenderwoche, i, j ,k, daymin, hourmin, daymax, hourmax); //c)
}
CodePudding user response:
In C programming for storing the values that you don't have their count without using any third party libraries, you have two main approaches. One way is to create an very large array and store your data into it, by using this approach you must have an upper bound for your number of inputs. Another way is using dynamic memory allocation. There are multiple ways for using dynamic memory allocation and one the simplest approach is using realloc
and increasing a dynamically allocated memory one by one (this solution is simple for implementation and may not good enough for memory/time consumption).
First approach:
int daymin[100] = {0};
int dayminindex = 0;
...
daymin[dayminindex] = j 1;
dayminindex ;
and the second approach is:
int *daymin = NULL;
int dayminlen = 0;
...
dayminlen ;
daymin = realloc(daymin, len * sizeof(int));
daymin[dayminlen - 1] = j 1;
After applying the second approach in your code, we will have:
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <limits.h>
double week_statistics(double array[52][7][24], int kalenderwoche){
int i, j, k;
int minlen = 0;
int *daymin = NULL;
int *hourmin = NULL;
double min = array[0][0][0];
for(i = 0; i < 52; i ){
for(j = 0; j < 7; j ){
for(k = 0; k < 24; k ){
if(array[i][j][k] < min) {
min = array[i][j][k];
minlen = 0;
free(daymin);
free(hourmin);
daymin = NULL;
hourmin = NULL;
}
// here we will add the first one
if(array[i][j][k] == min) {
minlen ;
daymin = realloc(daymin, minlen * sizeof(int));
daymin[minlen - 1] = j 1;
hourmin = realloc(hourmin, minlen * sizeof(int));
hourmin[minlen - 1] = k 1;
}
}
}
}
for (int i = 0; i < minlen; i ) {
printf("Die niedrigste Temperatur war %lf° in der %d. Kalenderwoche am %d. Wochentag um %d Uhr.\n", min, kalenderwoche, daymin[i], hourmin[i]);
}
int maxlen = 0;
int *daymax = NULL;
int *hourmax = NULL;
double max = array[0][0][0];
for(i = 0; i < 52; i ){
for(j = 0; j < 7; j ){
for(k = 0; k < 24; k ){
if(array[i][j][k] > max){
max = array[i][j][k];
maxlen = 0;
free(daymax);
free(hourmax);
daymax = NULL;
hourmax = NULL;
}
// here we will add the first one
if(array[i][j][k] == max){
maxlen ;
daymax = realloc(daymax, maxlen * sizeof(int));
daymax[maxlen - 1] = j 1;
hourmax = realloc(hourmax, maxlen * sizeof(int));
hourmax[maxlen - 1] = k 1;
}
}
}
}
for (int i = 0; i < maxlen; i ) {
printf("Die höchste Temperatur war %lf° in der %d. Kalenderwoche am %d. Wochentag um %d Uhr.\n", max, kalenderwoche, daymax[i], hourmax[i]);
}
}
int main(){
double array[52][7][24] = {
{
{9.6, 9.4, 9.3, 9.1, 7.9, 7.7, 7.3, 7.2, 8.8, 9.3, 9.7, 9.4, 10.2, 9.7, 9.9, 9.5, 9.2, 9.3, 9.2, 7.1, 6.1, 5.9, 5.6, 5.2},
{4.9, 4.6, 4.6, 4.1, 3.5, 3.1, 2.6, 2.6, 3.5, 5.1, 6.2, 8.3, 9.0, 9.3, 9.1, 8.0, 6.8, 6.4, 5.4, 5.2, 4.8, 4.5, 5.0, 5.5},
{6.3, 6.8, 7.0, 7.2, 7.1, 7.2, 7.1, 7.4, 7.7, 8.2, 8.7, 9.1, 8.8, 8.7, 8.6, 8.4, 8.0, 7.9, 7.7, 7.6, 7.5, 7.3, 7.3, 7.2},
{7.1, 7.0, 6.9, 6.8, 6.7, 6.7, 6.7, 6.6, 6.7, 6.8, 6.9, 7.2, 7.5, 7.7, 8.1, 8.3, 8.0, 7.7, 8.1, 8.2, 7.7, 7.5, 7.7, 7.9},
{8.1, 8.0, 7.9, 7.8, 7.5, 7.2, 6.9, 7.2, 8.0, 8.4, 8.7, 9.0, 8.7, 8.9, 9.0, 7.8, 8.5, 8.1, 7.7, 7.7, 6.7, 7.0, 6.5, 7.1},
{6.4, 6.6, 6.3, 5.8, 5.0, 4.9, 4.7, 4.6, 4.9, 5.3, 6.1, 5.5, 5.3, 5.7, 5.8, 6.5, 6.6, 5.8, 5.8, 7.1, 7.0, 7.0, 6.3, 5.8},
{4.4, 4.0, 3.8, 3.8, 4.2, 4.2, 4.3, 3.8, 4.4, 5.2, 5.7, 5.9, 6.1, 6.7, 6.3, 5.9, 5.5, 5.1, 5.0, 5.0, 5.2, 5.7, 7.2, 7.7}
}
};
int kalenderwoche = 45;
week_statistics(array, kalenderwoche);
}
CodePudding user response:
There is a third approach that sometimes preferable when you have a stream of values and you just care about the statistics, not the individual values. (As you seem to have here.) You can take the data on-line in a single pass, only updating the values you care about.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
struct measure {
size_t count;
/* On-line numerically stable first-order, <Welford, 1962, Note>. */
double mean, ssdm;
struct { double min, max; } value;
struct { size_t min, max; } arg_hour, arg_day;
};
static void m_add(struct measure *const m, const double replica,
const size_t hour, const size_t day) {
const size_t n = m->count;
const double delta = replica - m->mean;
m->mean = delta / n;
m->ssdm = delta * (replica - m->mean);
if(n == 1 || replica < m->arg_hour.min) m->arg_hour.min = hour; /* argmin */
if(n == 1 || replica > m->arg_hour.max) m->arg_hour.max = hour; /* argmax */
if(n == 1 || replica < m->arg_day.min) m->arg_day.min = day; /* argmin */
if(n == 1 || replica > m->arg_day.max) m->arg_day.max = day; /* argmax */
if(n == 1 || replica < m->value.min) m->value.min = replica;
if(n == 1 || replica > m->value.max) m->value.max = replica;
}
static double m_mean(const struct measure *const m)
{ return m->count ? m->mean : 0. / 0.; }
static double m_sample_variance(const struct measure *const m)
{ return m->count > 1 ? m->ssdm / (m->count - 1) : 0. / 0.; }
static double m_stddev(const struct measure *const m)
{ return sqrt(m_sample_variance(m)); }
int main(void) {
double array[][7][24] = {
{
{ 9.6, 9.4, 9.3, 9.1, 7.9, 7.7, 7.3, 7.2, 8.8, 9.3, 9.7, 9.4,
10.2, 9.7, 9.9, 9.5, 9.2, 9.3, 9.2, 7.1, 6.1, 5.9, 5.6, 5.2 },
{ 4.9, 4.6, 4.6, 4.1, 3.5, 3.1, 2.6, 2.6, 3.5, 5.1, 6.2, 8.3, 9.0,
9.3, 9.1, 8.0, 6.8, 6.4, 5.4, 5.2, 4.8, 4.5, 5.0, 5.5 },
{ 6.3, 6.8, 7.0, 7.2, 7.1, 7.2, 7.1, 7.4, 7.7, 8.2, 8.7, 9.1, 8.8,
8.7, 8.6, 8.4, 8.0, 7.9, 7.7, 7.6, 7.5, 7.3, 7.3, 7.2 },
{ 7.1, 7.0, 6.9, 6.8, 6.7, 6.7, 6.7, 6.6, 6.7, 6.8, 6.9, 7.2, 7.5,
7.7, 8.1, 8.3, 8.0, 7.7, 8.1, 8.2, 7.7, 7.5, 7.7, 7.9},
{ 8.1, 8.0, 7.9, 7.8, 7.5, 7.2, 6.9, 7.2, 8.0, 8.4, 8.7, 9.0, 8.7,
8.9, 9.0, 7.8, 8.5, 8.1, 7.7, 7.7, 6.7, 7.0, 6.5, 7.1},
{ 6.4, 6.6, 6.3, 5.8, 5.0, 4.9, 4.7, 4.6, 4.9, 5.3, 6.1, 5.5, 5.3,
5.7, 5.8, 6.5, 6.6, 5.8, 5.8, 7.1, 7.0, 7.0, 6.3, 5.8},
{ 4.4, 4.0, 3.8, 3.8, 4.2, 4.2, 4.3, 3.8, 4.4, 5.2, 5.7, 5.9, 6.1,
6.7, 6.3, 5.9, 5.5, 5.1, 5.0, 5.0, 5.2, 5.7, 7.2, 7.7 }
}
};
const int kalenderwoche = 45;
size_t j, k;
struct measure m = { 0 };
for(j = 0; j < sizeof *array / sizeof **array; j ) {
for(k = 0; k < sizeof **array / sizeof ***array; k ) {
m_add(&m, array[0][j][k], k 1, j 1);
}
}
printf("Die niedrigste Temperatur war %lf° in der %d. Kalenderwoche am %zu. Wochentag um %zu Uhr.\n"
"Die höchste Temperatur war %lf° in der %d. Kalenderwoche am %zu. Wochentag um %zu Uhr.\n"
"Mean %f /- %1.1f.\n",
m.value.min, kalenderwoche, m.arg_day.min, m.arg_hour.min,
m.value.max, kalenderwoche, m.arg_day.max, m.arg_hour.max,
m_mean(&m), m_stddev(&m));
}
I've also calculated the mean and standard-deviation using numerically-stable Welford's on-line algorithm using mean
and ssdm
, if you care about this.