How to make a loop that reads values and compares them to save growing sequences?

I have to make a program that reads values and says what is the highest ascending sequence of temperatures, at what position it starts and what is its length, but I'm not quite sure how to do it.

The program terminates if the number -1 is entered and that is when the result should be printed on the screen. I can only use basic commands like while, if else or up to for but not much more.

#include <iostream>
using namespace std;
int main(){
    setlocale(LC_CTYPE, "Spanish");
    double temperatura1, temperatura2;
    int contador1, contador2, posicion, contador3;

    temperatura2=0;
    contador2=0;
    contador1=0;
    contador3=0;

    while(temperatura1!=-1 && temperatura2!=-1){

        if(temperatura1!=-1 && temperatura2!=-1){
            cout << "Introduzca la temperatura: ";
            cin >> temperatura1;
        }

        if(temperatura1!=-1 && temperatura2!=-1){
            if(temperatura2>temperatura1){
                if(contador2>contador1)
                    contador1=contador2;
                contador2=1;
            }
        }   
        if(temperatura1!=-1 && temperatura2!=-1){
            contador3++;
            contador2++;
        }

        if(temperatura1!=-1 && temperatura2!=-1){
            cout << "Introduzca la temperatura: ";
            cin >> temperatura2;

        }
        if(temperatura1!=-1 && temperatura2!=-1){
            if(temperatura1>temperatura2){
                if(contador2>contador1)
                    contador1=contador2;
                contador2=1;
            }
        }
            if(temperatura1!=-1 && temperatura2!=-1){
            contador3++;
            contador2++;
            }
    }

    posicion=contador3-contador1-contador2+1;
    if(contador2>contador1){
        contador1=contador2;
        posicion=contador3-contador1+1;
    }
    cout << "\n" << posicion << "\n";
    cout << contador1;
}
 0
Author: Black Sheep, 2016-10-30

1 answers

It is important to mention that with float s and double s it is impossible to use the operators == or !=, because by saving, for example, a 1 in a variable of such type, in memory, said 1 could actually be saved as 1.00000001 or as 0.99999999999999999999 and the like. The same applies to -1 or any other floating point number, there are always accuracy issues.

As additional advice, use descriptive names (and not so many contadoris that one does not know what it is for each until the code is studied). And since longest_init is shorter than inicio_mas_larga, because the code goes in English (I tell you already, in English it is written less):

#include <iostream>
#include <cmath> // para std::abs (que no es lo mismo que `abs`).

using namespace std;

int main()
{
    int longest_init = 0, longest_end = 0;
    int curr_init = 0, curr_end = 0;

    double curr_temp, former_temp;

    cin >> former_temp;

    // Si la temperatura anterior es diferente a -1
    // (es decir, si no está pegado a `-1`).
    while (std::abs(former_temp - -1.) >= 0.0001) {

       ++curr_end;

       cin >> curr_temp;

       // Comprobar fin de secuencia, bien por -1, bien por no ascendiente
       // Comprobar si secuencia actual es mayor que la secuencia anterior
       if (std::abs(curr_temp - -1) < .0001 or curr_temp <= former_temp) {

           if ((curr_end - curr_init) > (longest_end - longest_init)) {
              longest_init = curr_init;
              longest_end = curr_end;
           }

           curr_init = curr_end;
       }

       former_temp = curr_temp;
    }

    cout << "Secuencia (inicio, longitud): (" << longest_init
         << ", " << (longest_end - longest_init) << ")" << endl;
}

Execute this code.

Various notes :

  • Regarding abs, keep in mind that abs is a function that comes from C, and for Backward Compatibility (C++ tries to be as backward compatible with C as it can, so that most C programs can be compiled with a C++ compiler), C++ has, for each C function, several functions with the same name. In the case of abs, there are two versions:

    • The simple function abs, which only works with integers abs(int), and which is not inside the namespace std (because C has no namespaces).

    • The function std::abs, with different overloads for int, floats, etc (in C, the other overloads are available via the {[23] functions]}, labs, etc).

    For that reason, even though I have already included using namespace std; at the beginning of the code, I re-specify std::abs to prevent the version of C (which has preference) from being chosen, and which only works with integers.

  • In case there are several maximum sequences (of the same size), the algorithm is left with the first of them.

  • The comparison I use to see if the sequence is decreasing (curr_temp <= former_temp), may crash you the fact that I used an equality comparison (<=) when just before I just said You can't be trusted for accuracy issues, and it's true. I've left it that way for simplicity as I'm not comparing with another constant, but with a previous element of the sequence (which suffers from the same accuracy issues), so we assume that the user is never going to manually enter values that are so similar to each other. In the case of -1 the comparison was mandatory because the user, in fact, can enter a -1 which the application then receives as a -0.99999. If you want to make the comparison a little more reliable, you can do something like:

    (curr_temp - .0001) <= former_temp
    

    Thus, somehow, we force that, if the current temperature is practically equal to the previous one, by subtracting a small value, we force it to be less than former_temp (whether or not to maintain the = to a certain extent is optional after subtraction). But I insist, if the user puts "normal" values" for a college exercise, you're not going to have problems, except with the -1, which Comparison by absolute subtraction if required.

 2
Author: Peregring-lk, 2016-10-31 12:22:01