Название: обобщение алгоритма
Отправлено: kambala от Июль 13, 2014, 01:30
по мотивам предыдущей темы про лямбды :) Имеется незамысловатый алгоритм на C++ (с небольшими примесями Objective-C, но это не страшно), состоящий из двух аналогичных частей, вторая написана копипастой: C++ (Qt) if (checkState != IgnoreHorizontal) { NumberGridLayer *numberLayer = self.gridsManager.verticalScrollView.gridView.gridLayer; uchar row = cell.row(); if (numberLayer.grid->lineLengthAtMainIndex(row) == 1) // only one number in the line { // it's the rightmost cell NumberCell &numberCell = numberLayer.grid->cellAt(row, numberLayer.grid->columns() - 1); // count how many cells are colored uchar colored = 0; for (uchar j = 0; j < cols; ++j) { if (grid.cellAt(row, j).state() == CellState::Colored) ++colored; else if (colored) // stop counting if it's not a solid colored line break; } if (colored == numberCell.number()) { // cross out the number if (numberCell.setState(CellState::Colored)) [numberLayer drawCell:numberCell]; // set other cells in the line to spacers for (uchar j = 0; j < cols; ++j) { GridCell &aCell = grid.cellAt(row, j); if (aCell.state() == CellState::Blank) { aCell.setState(CellState::Spacer); [nonogramLayer drawCell:aCell]; } } } } } if (checkState != IgnoreVertical) { NumberGridLayer *numberLayer = self.gridsManager.horizontalScrollView.gridView.gridLayer; uchar col = cell.column(); if (numberLayer.grid->lineLengthAtMainIndex(col) == 1) // only one number in the line { // it's the botommost cell NumberCell &numberCell = numberLayer.grid->cellAt(numberLayer.grid->rows() - 1, col); // count how many cells are colored uchar colored = 0; for (uchar i = 0; i < rows; ++i) { if (grid.cellAt(i, col).state() == CellState::Colored) ++colored; else if (colored) // stop counting if it's not a solid colored line break; } if (colored == numberCell.number()) { // cross out the number if (numberCell.setState(CellState::Colored)) [numberLayer drawCell:numberCell]; // set other cells in the line to spacers for (uchar i = 0; i < rows; ++i) { GridCell &aCell = grid.cellAt(i, col); if (aCell.state() == CellState::Blank) { aCell.setState(CellState::Spacer); [nonogramLayer drawCell:aCell]; } } } } }
Алгоритм выполняется для горизонтали и для вертикали, основное отличие — как считывать ячейку (в нескольких местах). Понятно, что можно сделать функцию с тучей параметров, но может есть способ получше? В дальнейшем будет еще несколько подобных алгоритмов (в смысле что некий алгоритм будет выполняться для горизонтали и для вертикали, опять же с отличием лишь в способе получении ячеек). P.S. Можем и алгоритмы (автоматического зачеркивания чисел в «японских кроссвордах») обсудить :)
Название: Re: обобщение алгоритма
Отправлено: Igors от Июль 13, 2014, 10:46
Я бы делал примерно так C++ (Qt) struct CCellIndexer { CCellIndexer( int x0, int x1, int y0, int y1 ); int x( int index ) const { return (x0 == x1) ? x0 : index; } int y( int index ) const { return (y0 == y1) ? y0 : index; } int beg( void ) const { return (x0 == x1) ? y0 : x0; } int end( void ) const { return (x0 == x1) ? y1 : x1; } private: int x0, x1, y0, y1; };
Название: Re: обобщение алгоритма
Отправлено: Old от Июль 13, 2014, 12:03
Я бы делал примерно так
Ну тут остался один маленьктй шажок и вы изобретёте итераторы. :) 2 kambala Попробуйте выделить процесс прохода по линии в отдельную сущность - итератор. Тогда алгоритму будет все равно, какая это линия вертикальная, горизонтальная или перпендикулярная. Он будет просто просить объект итератор вернуть следующую точку.
Название: Re: обобщение алгоритма
Отправлено: Igors от Июль 13, 2014, 12:43
Ну тут остался один маленьктй шажок и вы изобретёте итераторы. :)
Это не входило в мои планы, прямой доступ по индексу проще и лучше (щас загадят все - typedef и пр)
Название: Re: обобщение алгоритма
Отправлено: Old от Июль 13, 2014, 12:50
прямой доступ по индексу проще и лучше
Ну да, ну да. :) (щас загадят все - typedef и пр)
Лямбдами. typedef'ы это прошлый век, ими даже вы гадите направо и налево. :)
Название: Re: обобщение алгоритма
Отправлено: Igors от Июль 13, 2014, 13:44
Дальше можно парочку ф-ций напр C++ (Qt) NumberCell & LastCell( Grid & grid, const CCellIndexer & idx ) { return grid.cellAt(idx.x(idx.end() - 1)), idx.y(idx.end() - 1)); } NumberCell & IndexedCell( Grid & grid, const CCellIndexer & idx, int index ) { return grid.cellAt(idx.x(index), idx.y(index)); }
Название: Re: обобщение алгоритма
Отправлено: kambala от Июль 13, 2014, 14:05
спасибо, попробую и так и так. посмотрим что получится :)
Название: Re: обобщение алгоритма
Отправлено: kambala от Июль 13, 2014, 23:07
попытался сделать итератор для «линии» (определенная строка или столбец): вылезла лишняя работа при создании итератора для столбца (сетка хранится как двумерный массив — массив строк). а от индексатора в итоге отказался т.к. удалось сделать простенькую «лазейку» в классе сетки :)
|