Task description: In the input we have 6 days where we took measurements.
1st column is the morning measurements 2nd column is the evening measurements
we have to print the indexes (start and end) of the longest period where evening measurements were higher than morning measurements
I only want to print the indexes of the first and last element of an array where the array is continuous, for example:
The arr is {1, 6, 3, 4, 5}
the continuous elements are only: (3,4,5)
and the first and last elements are -> (3,5)
#include <iostream>
using namespace std;
struct Measure {
int morning, evening;
};
int main()
{
Measure measures[300];
int n, firstResult[100];
cin >> n;
for (int i = 0; i < n; i ) {
cin >> measures[i].morning >> measures[i].evening;
}
int counter = 0;
for (int i = 0; i < n; i ) {
if (measures[i].morning < measures[i].evening) {
counter ;
firstResult[counter] = i 1;
}
}
for (int i = 1; i <= counter; i ) {
cout << firstResult[i] << " ";
}
cout << endl;
return 0;
}
The input:
6
100 120
200 122
170 190
100 222
150 155
75 60
the output should be 3
and 5
because the array is continuous from the index 3rd
to 5th
but my code is giving 1 3 4 5
in output.
How can I only print the first and last element of the continuous portion.
CodePudding user response:
I suggest to use hardcoded input rather than reading via cin
for easier testing and debugging. And use std::vector
for a dynamically sized array (= you don't know the size until runtime):
std::stringstream ss{R"(100 120
200 122
170 190
100 222
150 155
75 60)"};
std::vector<Measure> measures;
Measure temp;
while (ss >> temp.morning >> temp.evening) measures.push_back(temp);
Next you should actually find the contiguous sequences of elements. In your code you merely count all elements where morning < evening
no matter where they are in the array. You can use a loop where you use a flag to remember if you are inside or outside a contiguous sequence. I strongly suggest to use 0-based indices always. If you are required to print 1-based indices as result you can still add one for the output.
std::vector<contiguous_sequence> find_contiguous_sequences(const std::vector<Measure>& m){
std::vector<contiguous_sequence> result;
contiguous_sequence current;
bool inside = false;
for (size_t i = 0; i < m.size(); i){
if (m[i].morning < m[i].evening) {
if (inside) continue;
inside = true; // state change: outside -> inside
current.begin = i;
} else {
if (inside) { // state change: inside outside
current.end = i;
inside = false;
result.push_back(current);
}
}
}
if (inside) { // check if the last element of the array was inside
current.end = m.size();
result.push_back(current);
}
return result;
}
Here inside
keeps track of whether you are inside a sequnce of morning < evening
elements. And begin and end of such sequences are stored in result
. Note that I used to convention of half open intervals, ie begin
is the first element in the sequence while end
is one past the last element in the sequence. You need to consider this when there is a sequence at the end of the vector. Then the last end
is not an element in the vector.
Calling this function with above input and printing its result:
auto cs = find_contiguous_sequences(measures);
for (const auto& e : cs ) std::cout << e.begin << " " << e.end << "\n";
results in
0 1
2 5
I'll leave it to you to find the largest sequence and print it.
CodePudding user response:
You have to remeber that you are inside a valid sequence and each time you enter a new valid sequence you have to reset your counter. Further you have to print just the forst and the last elements of the firstResult array. The code could be as below
#include <iostream>
using namespace std;
struct Measure {
int morning, evening;
};
int main()
{
Measure measures[300];
int n, firstResult[100];
cin >> n;
for (int i = 0; i < n; i ) {
cin >> measures[i].morning >> measures[i].evening;
}
int counter = 0;
bool counting = false;
for (int i = 0; i < n; i ) {
if (measures[i].morning < measures[i].evening)
{
if (!counting) {
counting = true;
counter = 0;
}
firstResult[counter ] = i 1;
}
else
{
counting = false;
}
}
if (counter > 0)
{
cout << firstResult[0] << " " << firstResult[counter - 1];
}
cout << endl;
return 0;
}