Russian Qt Forum
Ноябрь 23, 2024, 04:08 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: обобщение алгоритма  (Прочитано 4333 раз)
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



Просмотр профиля WWW
« : Июль 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. Можем и алгоритмы (автоматического зачеркивания чисел в «японских кроссвордах») обсудить Улыбающийся
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #1 : Июль 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;
};
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #2 : Июль 13, 2014, 12:03 »

Я бы делал примерно так
Ну тут остался один маленьктй шажок и вы изобретёте итераторы. Улыбающийся

2 kambala
Попробуйте выделить процесс прохода по линии в отдельную сущность - итератор.
Тогда алгоритму будет все равно, какая это линия вертикальная, горизонтальная или перпендикулярная. Он будет просто просить объект итератор вернуть следующую точку.
« Последнее редактирование: Июль 13, 2014, 12:06 от Old » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #3 : Июль 13, 2014, 12:43 »

Ну тут остался один маленьктй шажок и вы изобретёте итераторы. Улыбающийся
Это не входило в мои планы, прямой доступ по индексу проще и лучше
(щас загадят все - typedef и пр)

Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #4 : Июль 13, 2014, 12:50 »

прямой доступ по индексу проще и лучше
Ну да, ну да. Улыбающийся

(щас загадят все - typedef и пр)
Лямбдами. typedef'ы это прошлый век, ими даже вы гадите направо и налево. Улыбающийся
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #5 : Июль 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));  
}
 
Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



Просмотр профиля WWW
« Ответ #6 : Июль 13, 2014, 14:05 »

спасибо, попробую и так и так. посмотрим что получится Улыбающийся
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



Просмотр профиля WWW
« Ответ #7 : Июль 13, 2014, 23:07 »

попытался сделать итератор для «линии» (определенная строка или столбец): вылезла лишняя работа при создании итератора для столбца (сетка хранится как двумерный массив — массив строк). а от индексатора в итоге отказался т.к. удалось сделать простенькую «лазейку» в классе сетки Улыбающийся
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.118 секунд. Запросов: 22.