Обобщая эти строки кода?

Во время программирования я наткнулся на стену с некоторым кодом. Это выглядит так:

~ Цвета! ~

И это проблема. Я сделал красивый скриншот, чтобы уменьшить свою вину. Красивые цвета не компенсируют отсутствие ремонтопригодности. Я почти не представляю, как обобщать такой код.

Хорошо, рассмотрим периодичность 3-го и 6-го рассуждений. Это также согласуется с периодичностью других аргументов. Нечто подобное позволило бы нам преобразовать этот код в цикл с 9 строками, если мы используем массив. Это улучшение, когда мы идем вниз 66%. Однако этого недостаточно. Было бы лучше, если бы это было изменено, чтобы иметь 1 строка. Это, по крайней мере, сделало бы это немного более ремонтопригодны.

Ну, так сказать. Этот код там может быть неправильно.

9

Решение

Ну, это заняло некоторое время, чтобы проанализировать закономерности.

Конечно, сначала я использовал http://www.onlineocr.net/ чтобы получить текст со скриншота. Затем я начал выделять спички, чтобы определить шаблоны.

  • Ты это видишь make_cube эффективно занимает два (x,y,z) кортежи
  • Есть три группы или строки, которые заканчиваются в одном и том же z значение
  • Эти три группы состоят из трех подгрупп, которые заканчиваются в одном и том же (y,z) кортеж
  • Значения x, y и z перечисляют одинаковые пары значений для каждой группы.

Это делает его «очевидным» материалом для цикла генерации. После примерно 20 минут рефакторинга я был до

for (auto&& zs : { tie(rmin_z, imin_z), tie(imin_z, imax_z), tie(imax_z, rmax_z) })
for (auto&& ys : { tie(rmin_y, imin_y), tie(imin_y, imax_y), tie(imax_y, rmax_y) })
for (auto&& xs : { tie(rmin_x, imin_x), tie(imin_x, imax_x), tie(imax_x, rmax_x) })
{
*out++ = make_cube(get<0>(xs), get<0>(ys), get<0>(zs), get<1>(xs), get<1>(ys), get<1>(zs));
}

Но вы заметите регулярность в циклах. На самом деле у нас есть последовательность, как

coord const sequence[] = { rmin, imin, imax, rmax };

и мы выбираем последовательные пары: (rmin, imin), (imin, imax), (imax, rmax)

// we take all consecutive pairs (warning: ignoring the `(rmax, rmin)` closing pair here)
vector<pair<coord, coord>> pairs;
transform(begin(sequence), prev(end(sequence)), back_inserter(pairs), [](coord const& it) { return std::make_pair(*(&it+0), *(&it+1)); });

Теперь мы можем сделать это более напрямую. Я также изобрел простой Cube тип, который позволяет нам печатать результат цикла генератора, чтобы вы могли проверить результаты в DEBUG Режим:

for (auto zs : pairs) for (auto ys : pairs) for (auto xs : pairs)
*out++ = Cube { { xs.first.x, ys.first.y, zs.first.z }, { xs.second.x, ys.second.y, zs.second.z } };

Жить на Колиру

#include <iostream>
#include <algorithm>
#include <vector>
#include <array>

int main() {
#ifdef NDEBUG
typedef double T;
struct coord { T x,y,z; };

coord rmin { 0,  1,  2 },
imin { 3,  4,  5 },
imax { 6,  7,  8 },
rmax { 9, 10, 11 };
#else
typedef const char* T;
struct coord { T x,y,z; };

coord rmin { "rmin_x", "rmin_y", "rmin_z" },
imin { "imin_x", "imin_y", "imin_z" },
imax { "imax_x", "imax_y", "imax_z" },
rmax { "rmax_x", "rmax_y", "rmax_z" };
#endif
using namespace std;

// the source sequence
coord const sequence[] = { rmin, imin, imax, rmax };

// we take all consecutive pairs (warning: ignoring the `(rmax, rmin)` closing pair here)
vector<pair<coord, coord>> pairs;
transform(begin(sequence), prev(end(sequence)), back_inserter(pairs), [](coord const& it) { return std::make_pair(*(&it+0), *(&it+1)); });

// Now we build cubes. The `make_cube` interface implied it requires two
// coordinates to be constructed:
struct Cube { coord p1, p2; };
std::array<Cube, 3*3*3> cubes;

// generate!
auto out = cubes.begin();
for (auto zs : pairs) for (auto ys : pairs) for (auto xs : pairs)
*out++ = Cube { { xs.first.x, ys.first.y, zs.first.z }, { xs.second.x, ys.second.y, zs.second.z } };

// debug print
for(auto const& c : cubes)
std::cout << "make_cube(" << c.p1.x << ", " << c.p1.y << ", " << c.p1.z << ", " << c.p2.x << ", " << c.p2.y << ", " << c.p2.z << ")\n";
}

Выводы:

  1. Мой код выглядит сложнее. Это, вероятно, так и есть. Но это много легче увидеть, были ли сделаны опечатки
  2. По вопросу

    Это действительно проблема?

    Ну, так сказать. Этот код там может быть неправильно

    На самом деле, я немного сомневаюсь, покрыли ли вы все свои дела. Смотрите первый комментарий:

    // we take all consecutive pairs (warning: ignoring the `(rmax, rmin)` closing pair here)
    
16

Другие решения


По вопросам рекламы [email protected]