csearchlong-long

with Strings in c


I try to do interpolation search with the data from the struct. For example I give as input the time 2014-02-13T18:50:00 and I want interpolation search return the temp 4.0 and the hum 75 but something doesn't work. I think the problem appears when calculate mid with (High-Low)*(In-Low) but I don't understand why this happen.


#include <stdio.h>
#include <stdlib.h>



#define SIZE 11
struct metrhseis{
char time[21];
int temp;
int hum;

};
long long int string_To_long(const char  arr[]);
void interpolation_search(struct metrhseis  arr[], char * in);
int main(){

char in[25];
int inI;
int j;
struct  metrhseis s[SIZE];



strcpy(s[0].time, "2014-02-13T06:20:00");
s[0].temp=3.0;
s[0].hum=93;
strcpy(s[1].time, "2014-02-13T13:50:00");
s[1].temp=7.0;
s[1].hum=66;
strcpy(s[2].time, "2014-02-13T06:00:00");
s[2].temp=2;
s[2].hum=91;
strcpy(s[3].time, "2014-02-13T03:00:00");
s[3].temp=3;
s[3].hum=84;
strcpy(s[4].time, "2014-02-13T13:00:00");
s[4].temp=6;
s[4].hum=62;
strcpy(s[5].time, "2014-02-13T18:50:00");
s[5].temp=4.0;
s[5].hum=75;
strcpy(s[6].time, "2014-02-13T13:20:00");
s[6].temp=6.0;
s[6].hum=70;
strcpy(s[7].time, "2014-02-13T15:00:00");
s[7].temp=6;
s[7].hum=56;
strcpy(s[8].time, "2014-02-13T08:50:00");
s[8].temp=4.0;
s[8].hum=87;
strcpy(s[9].time, "2014-02-13T21:50:00");
s[9].temp=4.0;
s[9].hum=75;
strcpy(s[10].time, "2014-02-13T08:00:00");
s[10].temp=3;
s[10].hum=88;

 int i;



  for (i = 0; i < SIZE; i++)
     printf("%s\n%d\n%d\n", s[i].time,  s[i].temp,s[i].hum);

printf("Date:");
scanf("%s",in);
interpolation_search(s, in);


}
 void interpolation_search(struct metrhseis  arr[], char * in){
  long long int High,Low,In;
  long long int mid,low,high;
  low=0;
  high =SIZE - 1 ;
  High = string_To_long(arr[high].time);
  Low = string_To_long(arr[low].time);
  In = string_To_long(in);

  while(low<=high  ){
  High= string_To_long(arr[high].time);
  Low= string_To_long(arr[low].time);

  mid =low+(high-low)/(High-Low)*(In-Low);

  if(strcmp(arr[mid].time,in)>0){
  high=mid-1;
  }
  else if(strcmp(arr[mid].time,in)<0){
  low=mid+1;

 }
 else
 printf("Time: %s Temperatura: %d Hum: %d",arr[mid].time ,arr[mid].temp,arr[mid].hum);
 break;
}

printf("Time: %s Temperatura: %d Hum: %d", in,arr[mid].temp,arr[mid].hum);
}
long long string_To_long(const char arr[]) {
long long int n = 0;
for (int i = 0; arr[i] != '\0'; i++) {
    char c = arr[i];
    if (c >= '0' && c <= '9')
        n = n * 10 + (c - '0');
}
return n;
}

Solution

  • Use an ordered list Then compute ratio between two time and finally display temp and hum

    For 2014-02-13T13:40:00 get

    Time: 20140213134000 Temperatura: 6.666667 Hum: 67.333336

    #include <stdio.h>
    #include <stdlib.h>
    
    struct metrhseis{
        long long int time;
        int temp;
        int hum;
    
        struct metrhseis *next;
    };
    
    long long int string_To_long(const char  arr[]);
    void interpolation_search(struct metrhseis  *list, const char * in);
    void add_metrhseis(struct metrhseis **list, const char *time, int temp, int hum);
    void list_delete(struct metrhseis **list);
    void list_print(struct metrhseis *list);
    
    int main(){
    
        char in[25];
        struct  metrhseis *list = NULL;
    
        add_metrhseis(&list, "2014-02-13T06:20:00", 3.0, 93);
        add_metrhseis(&list, "2014-02-13T13:50:00", 7.0, 66);
        add_metrhseis(&list, "2014-02-13T06:00:00", 2, 91);
        add_metrhseis(&list, "2014-02-13T03:00:00", 3, 84);
        add_metrhseis(&list, "2014-02-13T13:00:00", 6, 62);
        add_metrhseis(&list, "2014-02-13T18:50:00", 4.0, 75);
        add_metrhseis(&list, "2014-02-13T13:20:00", 6.0, 70);
        add_metrhseis(&list, "2014-02-13T15:00:00", 6, 56);
        add_metrhseis(&list, "2014-02-13T08:50:00", 4.0, 87);
        add_metrhseis(&list, "2014-02-13T21:50:00", 4.0, 75);
        add_metrhseis(&list, "2014-02-13T08:00:00", 3, 88);
    
    
        list_print(list);
    
        printf("Date:");
        scanf("%s",in);
        interpolation_search(list, in);
    
        list_delete(&list);
    }
    
    void list_print(struct metrhseis *m) {
        printf("List\n");
        do {
            printf("%lld:%d,%d\n", m->time, m->temp, m->hum);
            m = m->next;
        } while (m);
    }
    
    void list_delete(struct metrhseis **list) {
        struct metrhseis *m = *list;
        if (m->next) {
            list_delete(&m->next);
        }
        free(m);
        *list = NULL;
    }
    void add_metrhseis(struct metrhseis **list, const char *time, int temp, int hum)
    {
        struct metrhseis *current = *list;
        struct metrhseis *m = malloc(sizeof(struct metrhseis));
        m->time = string_To_long(time);
        m->temp = temp;
        m->hum = hum;
    
        if (*list == NULL || (*list)->time > m->time) {
            m->next = *list;
            *list = m;
            return;
        }
        while (current->next && current->next->time <= m->time) {
            current = current->next;
        }
        m->next = current->next;
        current->next = m;
    }
    
    void interpolation_search(struct metrhseis *list, const char * in) {
        long long int time = string_To_long(in);
        float ratio;
    
        if (time < list->time) {
            printf("Time: %s Temperatura: %d Hum: %d\n", in, list->temp, list->hum);
            return;
        }
        while(list->next && list->next->time < time) {
            list = list->next;
        }
        if (!list->next) {
            printf("Time: %s Temperatura: %d Hum: %d\n", in, list->temp, list->hum);
            return;
        }
        ratio = (float)(time - list->time) / (list->next->time - list->time);
        printf("Time: %s Temperatura: %f Hum: %f\n",
               in,
               list->temp + ratio * (list->next->temp - list->temp),
               list->hum  + ratio * (list->next->hum  - list->hum )
        );
        return;
    
    }
    long long string_To_long(const char arr[]) {
        long long int n = 0;
        for (int i = 0; arr[i] != '\0'; i++) {
            char c = arr[i];
            if (c >= '0' && c <= '9')
                n = n * 10 + (c - '0');
        }
        return n;
    }