#include #include // In the previous exercise, we found the // second-largest unique entry by first finding // the largest entry. This required two for loops: // // 1. One inside the call to // // array_1st_rank(...) // // 2. A second loop in the body of // // array_2nd_rank(...) // // Rewrite array_2nd_rank(...) without making a // call to array_1st_rank(...) and without using // two loops. That is, you should pass through // the array exactly once. // // If there is no second-rank entry, return // capacity. This occurs if the array has fewer // than two distinct values. // Function declarations std::size_t array_2nd_rank( double const array[], std::size_t const capacity ); int main(); // Function definitions int main() { double array1[5]{ 3.2, 1.5, 4.9, 8.1, 2.4 }; double array2[7]{ 4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5 }; double array3[6]{ 1.2, 4.5, 4.5, 4.5, 4.5, 4.5 }; double array4[6]{ 1.2, 4.5, 4.5, 4.5, 4.5, 1.3 }; double array5[1]{ 1.2 }; double array6[7]{ 4.5, 1.5, 4.5, 1.5, 4.5, 1.5, 4.5 }; std::cout << array_2nd_rank( nullptr, 0 ) << " == 0" << std::endl; std::cout << array_2nd_rank( array1, 5 ) << " == 2" << std::endl; std::cout << array_2nd_rank( array2, 7 ) << " == 7" << std::endl; std::cout << array_2nd_rank( array3, 6 ) << " == 0" << std::endl; std::cout << array_2nd_rank( array4, 6 ) << " == 5" << std::endl; std::cout << array_2nd_rank( array5, 1 ) << " == 1" << std::endl; std::cout << array_2nd_rank( array6, 7 ) << " == 1" << std::endl; return 0; } // Determine the index of the second-largest unique // entry by passing through the array exactly once. // // At any point while processing the array, you will // need to remember both: // // 1. the index of the largest entry seen so far, // and // // 2. the index of the second-largest unique entry // seen so far. // // If no second-largest unique entry exists, return // capacity. std::size_t array_2nd_rank( double const array[], std::size_t const capacity ) { return capacity; } // You will need two indices and careful logic. // // Work through the examples above on paper. // // After examining each new entry, ask: // // 1. Is this entry greater than the largest // entry seen so far? // // If so, what happens to the old largest // entry? // // 2. Otherwise, is this entry strictly less // than the largest entry but greater than // the current second-largest entry? // // Remember that there may not yet be a // second-largest unique entry. You can represent // this by setting its index equal to capacity. // Here is one solution: /* std::size_t array_2nd_rank( double const array[], std::size_t const capacity ) { if ( capacity <= 1 ) { return capacity; } // Initially, assume the first entry is the // largest entry seen so far. No second-rank // entry has yet been found. std::size_t rank_1_idx{ 0 }; std::size_t rank_2_idx{ capacity }; for ( std::size_t k{ 1 }; k < capacity; ++k ) { if ( array[k] > array[rank_1_idx] ) { // The previous largest entry is now // the second-largest unique entry. rank_2_idx = rank_1_idx; rank_1_idx = k; } else if ( (array[k] < array[rank_1_idx]) && ((rank_2_idx == capacity) || (array[k] > array[rank_2_idx])) ) { rank_2_idx = k; } } return rank_2_idx; } */