#include #include #include /*************************************************** * INITIALIZING ARRAYS WITH SEQUENCES * * These functions initialize selected entries * of an array with one of three sequences: * * 1. Constant: * * c, c, c, c, ... * * 2. Arithmetic: * * a, a + d, a + 2d, a + 3d, ... * * Each entry differs from the preceding * entry by the common difference d. * * 3. Geometric: * * a, ar, ar^2, ar^3, ... * * Each entry is the preceding entry * multiplied by the common ratio r. * * Each function modifies the entries in * the half-open interval [begin, end). * * Preconditions: * * begin <= end * * The caller must ensure that end does not * exceed the capacity of the array. * * If begin == end, no entries are modified. * * All entries outside the specified interval * remain unchanged. ***************************************************/ // Function declarations int main(); void constant_array_init( double array[], std::size_t const begin, std::size_t const end, double const c ); void arithmetic_array_init( double array[], std::size_t const begin, std::size_t const end, double const a, double const d ); void geometric_array_init( double array[], std::size_t const begin, std::size_t const end, double const a, double const r ); void print_array( double const array[], std::size_t const capacity ); // Function definitions int main() { std::size_t const data_capacity{ 20 }; double data[data_capacity]{ 6.73, -0.52, -5.52, -8.43, 4.41, 1.19, 5.19, -1.40, 2.55, -9.02, 7.35, 7.34, 9.34, -0.06, 1.12, -2.73, 9.77, 4.71, 2.20, -9.28 }; // Save the original array so that we can // verify that entries outside [2, 12) // are never modified. double original[data_capacity]{}; for ( std::size_t k{ 0 }; k < data_capacity; ++k ) { original[k] = data[k]; } std::cout << "Original array:" << std::endl; print_array( data, data_capacity ); std::cout << "Constant sequence:" << std::endl; constant_array_init( data, 2, 12, 2.5 ); print_array( data, data_capacity ); for ( std::size_t k{ 2 }; k < 12; ++k ) { assert( data[k] == 2.5 ); } std::cout << "Arithmetic sequence:" << std::endl; arithmetic_array_init( data, 2, 12, 3.5, 1.5 ); print_array( data, data_capacity ); assert( data[2] == 3.5 ); assert( data[3] == 5.0 ); assert( data[4] == 6.5 ); assert( data[11] == 17.0 ); std::cout << "Geometric sequence:" << std::endl; geometric_array_init( data, 2, 12, 5.5, 1.1 ); print_array( data, data_capacity ); assert( data[2] == 5.5 ); // Check that the entries outside // [2, 12) have not changed. for ( std::size_t k{ 0 }; k < 2; ++k ) { assert( data[k] == original[k] ); } for ( std::size_t k{ 12 }; k < data_capacity; ++k ) { assert( data[k] == original[k] ); } // Empty intervals must leave // the array unchanged. constant_array_init( data, 5, 5, 10.0 ); arithmetic_array_init( data, 5, 5, 1.0, 2.0 ); geometric_array_init( data, 5, 5, 1.0, 2.0 ); // A zero-length array is also valid // when the specified interval is empty. constant_array_init( nullptr, 0, 0, 2.5 ); arithmetic_array_init( nullptr, 0, 0, 3.5, 1.5 ); geometric_array_init( nullptr, 0, 0, 5.5, 1.1 ); print_array( nullptr, 0 ); return 0; } /*************************************************** * Initialize the entries in [begin, end) * with the constant sequence * * c, c, c, ..., c. * * Every entry in the specified interval * is assigned the same value. ***************************************************/ void constant_array_init( double array[], std::size_t const begin, std::size_t const end, double const c ) { assert( begin <= end ); assert( array != nullptr || begin == end ); for ( std::size_t k{ begin }; k < end; ++k ) { array[k] = c; } } /*************************************************** * Initialize the entries in [begin, end) * with the arithmetic sequence * * a, a + d, a + 2d, ..., a + (n - 1)d, * * where n = end - begin. * * The first entry is a. Each subsequent * entry is obtained by adding d to the * preceding entry. ***************************************************/ void arithmetic_array_init( double array[], std::size_t const begin, std::size_t const end, double const a, double const d ) { assert( begin <= end ); assert( array != nullptr || begin == end ); // An empty interval requires no changes. if ( begin == end ) { return; } array[begin] = a; for ( std::size_t k{ begin + 1 }; k < end; ++k ) { array[k] = array[k - 1] + d; } } /*************************************************** * Initialize the entries in [begin, end) * with the geometric sequence * * a, ar, ar^2, ..., ar^(n - 1), * * where n = end - begin. * * The first entry is a. Each subsequent * entry is obtained by multiplying the * preceding entry by r. ***************************************************/ void geometric_array_init( double array[], std::size_t const begin, std::size_t const end, double const a, double const r ) { assert( begin <= end ); assert( array != nullptr || begin == end ); // An empty interval requires no changes. if ( begin == end ) { return; } array[begin] = a; for ( std::size_t k{ begin + 1 }; k < end; ++k ) { array[k] = r*array[k - 1]; } } /*************************************************** * Print the array as a comma-separated list * enclosed in braces. * * An empty array is printed as {}. ***************************************************/ void print_array( double const array[], std::size_t const capacity ) { assert( array != nullptr || capacity == 0 ); std::cout << "{"; if ( capacity != 0 ) { std::cout << array[0]; for ( std::size_t k{ 1 }; k < capacity; ++k ) { std::cout << ", " << array[k]; } } std::cout << "}" << std::endl; }