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;
}
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 contador
is 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 thatabs
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 ofabs
, there are two versions:The simple function
abs
, which only works with integersabs(int)
, and which is not inside thenamespace std
(because C has no namespaces).The function
std::abs
, with different overloads forint
,float
s, 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-specifystd::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.