Widząc tytuł “Zadanie” byłem przekonany, że za chwilę wkleję delikwentowi linki do tego lub tego wpisu. Jednak okazało się, że ów delikwent prosi o coś zupełnie innego, i nie mam tutaj na myśli lekcji poprawnego użycia liczb mnogiej i pojedynczej:
Zadanie 5
W tablicy jednowymiarowej A[50]: wyzeruj elementy większe od średniej z wszystkich elementów.
W odpowiedzi zastosowałem trochę C++17, żeby wykładowca nie musiał kłopotać się z przestarzałym kodem:
template<size_t N, typename T> void zero_elems(T* arr, double avg) { if constexpr(N > 0) { *arr = *arr > avg ? 0 : *arr; zero_elems<N-1>(arr+1, avg); } } template<typename T, size_t N> void zero_elems(T (&arr)[N]) { auto avg = std::accumulate(std::begin(arr), std::end(arr), 0.0, std::plus<>{}); avg /= N; zero_elems<N>(arr, avg); } |
Zadanie 9
W tablicy jednowymiarowej A[50]: zamień parzyste elementy na dwójki a nieparzyste na jedynki pod warunkiem, że ich indeksy są odpowiednio parzyste i nieparzyste.
Tutaj sprawa jest oczywiście mniej skomplikowana – nie ma potrzeby osobnego obliczania średniej, więc można po prostu sprawdzić wartości wszystkich elementów:
auto& elem_0 = A[0]; if(0 == (elem_0 & 1)) elem_0 = (2 >> 0); auto& elem_1 = A[1]; if(1 == (elem_1 & 1)) elem_1 = (2 >> 1); auto& elem_2 = A[2]; if(0 == (elem_2 & 1)) elem_2 = (2 >> 0); auto& elem_3 = A[3]; if(1 == (elem_3 & 1)) elem_3 = (2 >> 1); auto& elem_4 = A[4]; if(0 == (elem_4 & 1)) elem_4 = (2 >> 0); auto& elem_5 = A[5]; if(1 == (elem_5 & 1)) elem_5 = (2 >> 1); auto& elem_6 = A[6]; if(0 == (elem_6 & 1)) elem_6 = (2 >> 0); auto& elem_7 = A[7]; if(1 == (elem_7 & 1)) elem_7 = (2 >> 1); auto& elem_8 = A[8]; if(0 == (elem_8 & 1)) elem_8 = (2 >> 0); auto& elem_9 = A[9]; if(1 == (elem_9 & 1)) elem_9 = (2 >> 1); auto& elem_10 = A[10]; if(0 == (elem_10 & 1)) elem_10 = (2 >> 0); auto& elem_11 = A[11]; if(1 == (elem_11 & 1)) elem_11 = (2 >> 1); auto& elem_12 = A[12]; if(0 == (elem_12 & 1)) elem_12 = (2 >> 0); auto& elem_13 = A[13]; if(1 == (elem_13 & 1)) elem_13 = (2 >> 1); auto& elem_14 = A[14]; if(0 == (elem_14 & 1)) elem_14 = (2 >> 0); auto& elem_15 = A[15]; if(1 == (elem_15 & 1)) elem_15 = (2 >> 1); auto& elem_16 = A[16]; if(0 == (elem_16 & 1)) elem_16 = (2 >> 0); auto& elem_17 = A[17]; if(1 == (elem_17 & 1)) elem_17 = (2 >> 1); auto& elem_18 = A[18]; if(0 == (elem_18 & 1)) elem_18 = (2 >> 0); auto& elem_19 = A[19]; if(1 == (elem_19 & 1)) elem_19 = (2 >> 1); auto& elem_20 = A[20]; if(0 == (elem_20 & 1)) elem_20 = (2 >> 0); auto& elem_21 = A[21]; if(1 == (elem_21 & 1)) elem_21 = (2 >> 1); auto& elem_22 = A[22]; if(0 == (elem_22 & 1)) elem_22 = (2 >> 0); auto& elem_23 = A[23]; if(1 == (elem_23 & 1)) elem_23 = (2 >> 1); auto& elem_24 = A[24]; if(0 == (elem_24 & 1)) elem_24 = (2 >> 0); auto& elem_25 = A[25]; if(1 == (elem_25 & 1)) elem_25 = (2 >> 1); auto& elem_26 = A[26]; if(0 == (elem_26 & 1)) elem_26 = (2 >> 0); auto& elem_27 = A[27]; if(1 == (elem_27 & 1)) elem_27 = (2 >> 1); auto& elem_28 = A[28]; if(0 == (elem_28 & 1)) elem_28 = (2 >> 0); auto& elem_29 = A[29]; if(1 == (elem_29 & 1)) elem_29 = (2 >> 1); auto& elem_30 = A[30]; if(0 == (elem_30 & 1)) elem_30 = (2 >> 0); auto& elem_31 = A[31]; if(1 == (elem_31 & 1)) elem_31 = (2 >> 1); auto& elem_32 = A[32]; if(0 == (elem_32 & 1)) elem_32 = (2 >> 0); auto& elem_33 = A[33]; if(1 == (elem_33 & 1)) elem_33 = (2 >> 1); auto& elem_34 = A[34]; if(0 == (elem_34 & 1)) elem_34 = (2 >> 0); auto& elem_35 = A[35]; if(1 == (elem_35 & 1)) elem_35 = (2 >> 1); auto& elem_36 = A[36]; if(0 == (elem_36 & 1)) elem_36 = (2 >> 0); auto& elem_37 = A[37]; if(1 == (elem_37 & 1)) elem_37 = (2 >> 1); auto& elem_38 = A[38]; if(0 == (elem_38 & 1)) elem_38 = (2 >> 0); auto& elem_39 = A[39]; if(1 == (elem_39 & 1)) elem_39 = (2 >> 1); auto& elem_40 = A[40]; if(0 == (elem_40 & 1)) elem_40 = (2 >> 0); auto& elem_41 = A[41]; if(1 == (elem_41 & 1)) elem_41 = (2 >> 1); auto& elem_42 = A[42]; if(0 == (elem_42 & 1)) elem_42 = (2 >> 0); auto& elem_43 = A[43]; if(1 == (elem_43 & 1)) elem_43 = (2 >> 1); auto& elem_44 = A[44]; if(0 == (elem_44 & 1)) elem_44 = (2 >> 0); auto& elem_45 = A[45]; if(1 == (elem_45 & 1)) elem_45 = (2 >> 1); auto& elem_46 = A[46]; if(0 == (elem_46 & 1)) elem_46 = (2 >> 0); auto& elem_47 = A[47]; if(1 == (elem_47 & 1)) elem_47 = (2 >> 1); auto& elem_48 = A[48]; if(0 == (elem_48 & 1)) elem_48 = (2 >> 0); auto& elem_49 = A[49]; if(1 == (elem_49 & 1)) elem_49 = (2 >> 1); |
Wersja @hauleth
Wyżej wymieniony pan zasugerował, że powyższe zadanie można wykonać w następujący sposób:
void clamp(int *arr, size_t size) { int *i = arr; do { *i = (*i & 1) ^ ((i - arr) & 1) ? *i : ((~(i - arr) & 1) + 1); } while (++i - arr < (ptrdiff_t)size); } |
Nie znam tych nowych standardów C++’a, ale czy w zadaniu 5 w wierszu 13 nie powinno być & przed arr?
zero_elems(&arr, avg);
W tej dolnej funkcji arr jest referencją, a w górnej masz wskaźnik.
Nie, jest dobrze. Tablice w C (a zatem i w C++) automatycznie decayują (brak mi polskiego słowa) do wskaźnika na pierwszy element. Niemniej jednak, w pierwszej funkcji zero_elems parametrem jest wskaźnik, i wywołujemy też wersję ze wskaźnikiem, więc nie ma potrzeby pobierania jego adresu.