Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как избавиться от повторения кода, Нужно красивое решение 
V
    Опции темы
Voldemar2004
Дата 17.11.2006, 23:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1650
Регистрация: 25.12.2004

Репутация: нет
Всего: 23



У меня такой вопрос: как избавиться от повторения одного и того же кода. Например у меня есть функция сортировки прямым выбором:
Код
Straight_Sort(int key, int count, int *array)
{
                        if( key > 0 )
                        {

                                /* n-1 раз ищем наименьший элемент: */
                                for(unsigned int i = 0; i < count-1; ++i)
                                {
                                /* принимаем за наименьший 1-ый из рассматриваемых элементов: */
                                unsigned int imin = i;

                                /* поиск номера минимального элемента из неупорядоченных. */
                                for(unsigned int j = i + 1; j < count; ++j)

                                        /* если нашли меньший элемент, запоминаем его номер: */
                                        if (array[j] < array[imin]) imin = j;

                                        float buffer = array[i]; /* обмен элементов */
                                        array[i] = array[imin];  /* с номерами */
                                        array[imin] = buffer;    /* i и imin */

                                }

                        }

                        else
                        {
                                /* n-1 раз ищем наибольший элемент: */
                                for(unsigned int i = 0; i < count-1; ++i)
                                {
                                /* принимаем за наибольший 1-ый из рассматриваемых элементов: */
                                unsigned int imax = i;

                                /* поиск номера наибольшего элемента из неупорядоченных. */
                                for(unsigned int j = i + 1; j < count; ++j)

                                        /* если нашли наибольший элемент, запоминаем его номер: */
                                        if (array[j] > array[imax]) imax = j;

                                        float buffer = array[i]; /* обмен элементов */
                                        array[i] = array[imax];  /* с номерами */
                                        array[imax] = buffer;    /* i и imax */

                                }

                        };

}


Как бы покрасивее избавиться от повторения кода, ведь код
Код
float buffer = array[i]; /* обмен элементов */
array[i] = array[imax];  /* с номерами */
array[imax] = buffer;    /* i и imax */
повторяется 2 раза.

В книге нашел:
Цитата
Класс, в котором определена операция вызова функции, называется функциональным.
Код
class if_greater{
public:
int operator () (int a, int b) const {
return a > b;
}
};
Можно этот класс как-то использовать в данном случае?

В результате:
Код

if_greater x;
cout << x(1, 5) << endl;
cout << if_greater()(5, 1) << endl;



--------------------
i_i 
(';') 
(V)

user posted image
PM MAIL   Вверх
vinter
Дата 17.11.2006, 23:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 13
Всего: 56



ИМХО самое простое, засунь в inline ф-ию..


--------------------
Мой блог
PM MAIL WWW   Вверх
Voldemar2004
Дата 17.11.2006, 23:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1650
Регистрация: 25.12.2004

Репутация: нет
Всего: 23



Цитата(vinter @  18.11.2006,  00:41 Найти цитируемый пост)
inline
inline, как много в этом звуке... Но тогда придется создавать inline ф-цию, чтобы вставлять ее инлайн-методом в тело другой (сортировки) функции. И по-моему я читал, что компилятор сам определяет, определить ф-цию, как inline или нет.



--------------------
i_i 
(';') 
(V)

user posted image
PM MAIL   Вверх
Kuvaldis
Дата 17.11.2006, 23:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


механик-вредитель
***


Профиль
Группа: Участник Клуба
Сообщений: 1189
Регистрация: 16.6.2006
Где: Минск

Репутация: 11
Всего: 61



Voldemar2004, 
Код

#include <algorithm>
....
swap(array[i] , array[imax]); 



--------------------
Помни - когда ты спишь, враг не дремлет
Спи чаще и дольше, изматывай врага бессоницей
PM MAIL ICQ   Вверх
sergejzr
Дата 18.11.2006, 00:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Un salsero
Group Icon


Профиль
Группа: Админ
Сообщений: 13285
Регистрация: 10.2.2004
Где: Германия г .Ганновер

Репутация: 19
Всего: 360



А почему в простую функцию типа:


Код

void exchange(float * array, int idx1, int idx2)
{
  float buffer = array[idx1]; /* обмен элементов */
  array[idx1] = array[idx2];  /* с номерами */
  array[idx2] = buffer;    /* i и imax */
}   
void exchange(float &f1, ifloat &f2)
{
  float buffer = f1; /* обмен элементов */
  f1 = f2;  /* с номерами */
  f2 = buffer;    /* i и imax */
}   


Вообще конечно можно шаблоном для разных типов это сделать. 
Код

template <class T>
void exchange(T* array, int idx1, int idx2)
{
  T buffer = array[idx1]; /* обмен элементов */
  array[idx1] = array[idx2];  /* с номерами */
  array[idx2] = buffer;    /* i и imax */
}

template <class T>
void exchange( T &f1,T &f2)
{
  T buffer = f1; /* обмен элементов */
  f1 = f2;  /* с номерами */
  f2 = buffer;    /* i и imax */
}


Но я бы например  макрос написал (Хоть знаю, что С++ шники макросы не любят, но ИМХО тут подходит smile )

Код

#define exchange(array,a,b) {int *ai=(int*)(&array[a]); int *bi=(int*)(&array[b]); (*ai)^=(*bi);(*bi)^=(*ai);(*ai)^=(*bi);}
//вызов: 
exchange(buffer,i,imax);

Ты не смотри, что буков много. Компилер это соптимирует практически в 3 строкиsmile

Добавлено @ 00:15 
O, Kuvaldis дело говорит, нефиг велик изобретать  smile smile))


--------------------
PM WWW IM ICQ Skype GTalk Jabber AOL YIM MSN   Вверх
Kuvaldis
Дата 18.11.2006, 00:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


механик-вредитель
***


Профиль
Группа: Участник Клуба
Сообщений: 1189
Регистрация: 16.6.2006
Где: Минск

Репутация: 11
Всего: 61



sergejzr, 
1. Не хочу тебя огорчать, но зачем писать свое, если есть стандартная шаблонная функция swap() из STL, проверенная и быстро работающая.

2.  
Код

#define exchange(array,a,b) {int *ai=(int*)(&array[a]); int *bi=(int*)(&array[b]); (*ai)^=(*bi);(*bi)^=(*ai);(*ai)^=(*bi);}

Есть хороший способ писать макросы красиво, в несколько строчек - использование символа \ (я когда узнал, был очень рад)
Код

#define exchange(array,a,b) \
                 {int *ai=(int*)(&array[a]); \
                  int *bi=(int*)(&array[b]); \
                  (*ai)^=(*bi);\
                  (*bi)^=(*ai);\
                  (*ai)^=(*bi);}


Но макросы использовать - это ОЧЕНЬ плохо
1. Их нельзя отлаживать
2. В них могут быть неявные присвоения
3. Не экономно расходуется память 
4. НЕТ ПРОВЕРКИ на соответствие типов.
5. Не очень удобно писать


--------------------
Помни - когда ты спишь, враг не дремлет
Спи чаще и дольше, изматывай врага бессоницей
PM MAIL ICQ   Вверх
sergejzr
Дата 18.11.2006, 00:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Un salsero
Group Icon


Профиль
Группа: Админ
Сообщений: 13285
Регистрация: 10.2.2004
Где: Германия г .Ганновер

Репутация: 19
Всего: 360




Цитата(Kuvaldis @  17.11.2006,  23:26 Найти цитируемый пост)
1. Не хочу тебя огорчать, но зачем писать свое, если есть стандартная шаблонная функция swap() из STL, проверенная и быстро работающая.

Я же уже отписался насчёт неё.   smile (Насчёт "быстро" я бы не стал утверждать. Кто её знает, как она реализована  smile  (шутка))

Цитата(Kuvaldis @  17.11.2006,  23:26 Найти цитируемый пост)
Есть хороший способ писать макросы красиво, в несколько строчек - использование символа \ (я когда узнал, был очень рад)

Я знаю, но тогда как раз он становится похож на код. Это как раз может запутать. Но это уже по вкусу.

На мелочи вроде этого - макросы не страшны. Нельзя сказать в общем виде, что плохо, а что хорошо. Это как GОТО.
Все 5 пунктов в данном случае не важны. А есть вещи, которые без макроса вообще не сделать никак.

PS:
В данном случае это просто способ не использовать вызовы функции




--------------------
PM WWW IM ICQ Skype GTalk Jabber AOL YIM MSN   Вверх
Kuvaldis
Дата 18.11.2006, 00:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


механик-вредитель
***


Профиль
Группа: Участник Клуба
Сообщений: 1189
Регистрация: 16.6.2006
Где: Минск

Репутация: 11
Всего: 61



sergejzr, 
Цитата

Все 5 пунктов в данном случае не важны. А есть вещи, которые без макроса вообще не сделать никак.

К сожалению, это не тот случай, имхо.
Насчет макросов  - еще неплохая штука- макрос assert.
 
Цитата

В данном случае это просто способ не использовать вызовы функции

Лучше уж inline функцию, из-за 5 пунктов...
Т.е. если альтернативы макросам нет, то придется использовать, иначе...


--------------------
Помни - когда ты спишь, враг не дремлет
Спи чаще и дольше, изматывай врага бессоницей
PM MAIL ICQ   Вверх
Dov
Дата 18.11.2006, 01:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


аСинизатор
***


Профиль
Группа: Завсегдатай
Сообщений: 1721
Регистрация: 10.5.2003
Где: Эрец-Исраэль

Репутация: 15
Всего: 88



Цитата(Voldemar2004 @  17.11.2006,  23:36 Найти цитируемый пост)
 как избавиться от повторения одного и того же кода.

Voldemar2004, бери и не мучайся
Код
void Straight_Sort(int key, int count, int *array)
{
    for(int i = 0; i < count-1; ++i)                       
    {            
        int minmax = i;                                 
        for(int j = i + 1; j < count; ++j)            
            if((array[key ? j : minmax] < array[key ? minmax : j]))
                minmax = j;
            
        int buffer    = array[i];                               
        array[i]      = array[minmax];                     
        array[minmax] = buffer;                           
    }    
}





--------------------
Тут вечности запах томительный,
И свежие фрукты дешевые, 
А климат у нас – изумительный, 
И только соседи – #уевые. 
                           Игорь Губерман.
PM   Вверх
Voldemar2004
Дата 20.11.2006, 19:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1650
Регистрация: 25.12.2004

Репутация: нет
Всего: 23



Проблема решена.


--------------------
i_i 
(';') 
(V)

user posted image
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0639 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.