Re[5]: Убить goto
От: kan_izh Великобритания  
Дата: 17.02.06 14:03
Оценка: +1 -1 :)
Шахтер wrote:

>> > А>Если подразумевается классическое слияние то одной строчки не хватает:

>> > Нет, строится объединения множеств. Результирующая выходная
>> > последовательность строго монотонная.
> _>А чем std::set_union не устраивает? Там, кстати, нет goto (по крайней
> мере в MSVC7.1 имплементации).
> Этот вопрос оффтопик и вообще идиотский.
> Не пробовал в автомобиль на бензиновом движке заливать диз-топливо?
Если говорить метафорами, то твой вопрос выглядит "Я вот тут изобрёл велосипед, но колесо квадратное. Кто сможет
выпрямить?". Я лишь порекомендовал взглянуть на уже готовый. Не устраивает, так не устраивает, но хоть посмтотри как
круглые колёса делаются.
Posted via RSDN NNTP Server 2.0
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[4]: Убить goto
От: Шахтер Интернет  
Дата: 20.02.06 14:00
Оценка: +2
Здравствуйте, Cyberax, Вы писали:

C>Шахтер wrote:

>> Упустил то, что невозможен двухуровневый break.
>> Тут правда можно использовать break; -- continue;
C>По-моему, исходный вариант с goto был понятнее

Дык о том и речь. Мне кажется, что данный пример демонстрирует вредность догм в программировании. Одна из таких догм -- не используй goto.
Обычно он не нужен. Но иногда его использование совершенно оправдано.
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[10]: Дело вкуса.
От: Шахтер Интернет  
Дата: 24.02.06 15:31
Оценка: +1 :)
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, Шахтер, Вы писали:


Ш>>Для меня красота в программировании -- это функциональность и экономность.

E>А "
Ш>>дама, заросшая жиром, некрасива
E>" -- это нефункционально или неэкономно?

И то, и другое.
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re: Убить goto
От: Olegator  
Дата: 18.02.06 21:05
Оценка: 10 (1)
Здравствуйте, Шахтер, Вы писали:

Ш>Что-то много всякой фигнёй в последнее время страдаем (особенно философской).


Ш>Вот фрагмент кода (слияние двух отсортированных последовательностей).

Ш>Задача -- красиво убить goto.

А можно ли в объединяемые множества добавить по элементу? Если да, то нужно вставить в концы обеих последовательностей бесконечность.
... << RSDN@Home 1.1.4 stable rev. 510>>
Re: Убить goto
От: Vain Россия google.ru
Дата: 20.02.06 12:53
Оценка: 10 (1)
Здравствуйте, Шахтер, Вы писали:

Ш>Что-то много всякой фигнёй в последнее время страдаем (особенно философской).


Ш>Вот фрагмент кода (слияние двух отсортированных последовательностей).

Ш>Задача -- красиво убить goto.

template <class Range> 
template <class Collector>
typename ResultAttributes<typename Collector::FunctorType>::ResultType 
 UnionGenType<Range>::operator () (Collector collector) const
 {
  Range a=a_,b=b_;
  
  typedef typename Collector::FunctorType FunctorType;
  
  FunctorType fun(collector);
  
  struct FINISH_HIM {
    static A(Range& a,FunctorType& fun) {
      for(; +a ;++a) fun(*a);
    }
    static B(Range& b,FunctorType& fun) {
      for(; +b ;++b) fun(*b);
    }
  };

  if( !a ) FINISH_HIM::B(b,fun);
  else if( !b ) FINISH_HIM::A(a,fun);
  else
  for(;;)
    switch( Cmp(*a,*b) ) {
       case CmpLess: {
         fun(*a);
         ++a;             
         if( !a ) {
           FINISH_HIM::B(b,fun);
           break;
         }
       } break;           
       case CmpGreater: {
         fun(*b);
         ++b;
         if( !b ) {
           FINISH_HIM::A(a,fun);
           break;
         }
       } break;
       case CmpEqual: {
         fun(*a);
         ++a;
         ++b;
         if( !a ) {
           FINISH_HIM::B(b,fun);
           break;
         }
         if( !b ) {
           FINISH_HIM::A(a,fun);
           break;
         }
       } break; // :)
    }  
  return ResultAttributes<FunctorType>::GetResult(fun);
 }


мож что-где упустил, но общий аргумент должен быть ясен.. Ж)
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re[4]: Убить goto
От: Андрей Тарасевич Беларусь  
Дата: 01.03.06 01:17
Оценка: 5 (1)
Здравствуйте, Андрей Тарасевич, Вы писали:

А>>>Если подразумевается классическое слияние то одной строчки не хватает:


Ш>>Нет, строится объединения множеств. Результирующая выходная последовательность строго монотонная.


АТ>Так, так, так... Если предположить не строго монотонные входные последовательности, то этот алгоритм будет для каждой "постоянной" подпоследовательности выбирать более длинную (из присутствующих в двух входных массивах). Является ли это существенно частью спецификации? Или все таки можно сразу завязываться на тот факт, что входные последовательности строго монотонны. Если да, то это несколько меняет дело...


При наличии такой гарантии можно предложить следующий вариант (предполагая, что значения 'CmpLess', 'CmpEqual' и 'CmpGreater' сравнимы через операторы сравнения и дают именно такой порядок, а также что итераторы удволетворяют требованиям 'std::swap')

std::pair<int> cmp(CmpEqual, CmpLess);

while (a)
  for (std::swap(a, b), std::swap(cmp.first, cmp.second); a && Cmp(*a, *b) <= cmp.first; ++a)
    fun(*a);

for (; b; ++b)
  fun(*b);


Требование 'std::swap' можно, разумеется, обойти через указатели.

Можно также сделать так

do
{
  for (; a && (!b || Cmp(*a, *b) <= CmpEqual); ++a)
    fun(*a);

  for (; b && (!a || Cmp(*a, *b) > CmpEqual); ++b)
    fun(*b);

} while (a)


Хотя это просто не особо осмысленная попытка избавиться от отдельного обработчика "хвоста".

Ну и Настоящий Хакер, разумеется, воспользуется чем-то вроде Duff's device для избежания лишней проверки в вырожденном случае

switch (!a)
{
  do
  {
    case false:
      for (; a && (!b || Cmp(*a, *b) <= CmpEqual); ++a)
        fun(*a);

    case true:
      for (; b && (!a || Cmp(*a, *b) > CmpEqual); ++b)
        fun(*b);

  } while (a);
}


Бред, но не каждый же день подвернется возможность использовать Duff's device
Best regards,
Андрей Тарасевич
Re[8]: Убить goto
От: Шахтер Интернет  
Дата: 21.02.06 10:33
Оценка: :)
Здравствуйте, night beast, Вы писали:

NB>это всего лишь показывает, что красивый код не всегда самый быстрый, и наоборот.


Для меня красота в программировании -- это функциональность и экономность.
Так же как и в жизни -- дама, заросшая жиром, некрасива.
Но это, конечно, дело вкуса.
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re: Убить goto
От: mcf  
Дата: 03.03.06 23:23
Оценка: -1
Здравствуйте, Шахтер, Вы писали:

Ш>Что-то много всякой фигнёй в последнее время страдаем (особенно философской).


Фигня поскипана.

Решение — заменить финиш а, финиш Бэ на функции и не париться, лучшего решения нет. Учим матчасть.
Убить goto
От: Шахтер Интернет  
Дата: 16.02.06 13:43
Оценка:
Что-то много всякой фигнёй в последнее время страдаем (особенно философской).

Вот фрагмент кода (слияние двух отсортированных последовательностей).
Задача -- красиво убить goto.


template <class Range> 
template <class Collector>
typename ResultAttributes<typename Collector::FunctorType>::ResultType 
 UnionGenType<Range>::operator () (Collector collector) const
 {
  Range a=a_,b=b_;
  
  typedef typename Collector::FunctorType FunctorType;
  
  FunctorType fun(collector);
  
  if( !a ) goto finish_b;
  if( !b ) goto finish_a;
  
  for(;;)
    switch( Cmp(*a,*b) )
      {
       case CmpLess :
        {
         fun(*a);
         ++a;
             
         if( !a ) goto finish_b;
        }
       break;
           
       case CmpGreater :
        {
         fun(*b);
         ++b;
             
         if( !b ) goto finish_a;
        }
       break;
           
       case CmpEqual :
        {
         fun(*a);
         ++a;
         ++b;
             
         if( !a ) goto finish_b;
         if( !b ) goto finish_a;
        }  
      }  
      
  finish_a:
  
  for(; +a ;++a) fun(*a);   
  
  goto finish;
  
  finish_b:
  
  for(; +b ;++b) fun(*b);   
  
  finish:
  
  return ResultAttributes<FunctorType>::GetResult(fun);
 }
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re: Убить goto
От: Кодт Россия  
Дата: 16.02.06 14:34
Оценка:
Здравствуйте, Шахтер, Вы писали:

Красиво, но несколько затратно (делаем лишние проверки).
while(a && b)
{
  switch(Cmp(*a,*b))
  {
  case CmpLess:    fun(*a); ++a; break;
  case CmpEqual:   fun(*a); ++a; ++b; break;
  case CmpGreater: fun(*b); ++b; break;
  }
}
while(a) { fun(*a); ++a; }
while(b) { fun(*b); ++b; }


Чтобы сэкономить — кешируем результаты проверок.
bool af=a, bf=b;
while(af && bf)
{
  switch(Cmp(*a,*b))
  {
  case CmpLess:    fun(*a); ++a; af=a; break;
  case CmpEqual:   fun(*a); ++a; af=a; ++b; bf=b; break;
  case CmpGreater: fun(*b); ++b; bf=b; break;
  }
}
if(af)
  do { fun(*a); ++a; } while(a);
else
if(bf)
  do { fun(*b); ++b; } while(b);

Наконец, можно делать вот так
#define try_finish(x,y) if(!(x)) { while(y) { fun(*(y)); ++(y); } return; }
// или инлайн-функцией

try_finish(a,b);
try_finish(b,a);

while(true)
{
  switch(Cmp(*a,*b))
  {
  case CmpLess:    fun(*a); ++a;      try_finish(a,b); break;
  case CmpGreater: fun(*b); ++b;      try_finish(b,a); break;
  case CmpEqual:   fun(*a); ++a; ++b; try_finish(a,b); try_finish(b,a);
  }
}
Перекуём баги на фичи!
Re[2]: Убить goto
От: night beast СССР  
Дата: 16.02.06 14:44
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, Шахтер, Вы писали:


К>Красиво, но несколько затратно (делаем лишние проверки).

К>
К>while(a && b)
К>{
К>  switch(Cmp(*a,*b))
К>  {
К>  case CmpLess:    fun(*a); ++a; break;
К>  case CmpEqual:   fun(*a); ++a; ++b; break;
К>  case CmpGreater: fun(*b); ++b; break;
К>  }
К>}
К>while(a) { fun(*a); ++a; }
К>
К>


for ( ; ;) {
   if ( !a ) { while(b) { fun(*b); ++b; } break; }
   if ( !b ) { while(a) { fun(*a); ++a; } break; }

   switch (...)
}

Поправлено форматирование. — Кодт
Re: Убить goto
От: srggal Украина  
Дата: 16.02.06 15:10
Оценка:
Здравствуйте, Шахтер, Вы писали:

Ш>Вот фрагмент кода (слияние двух отсортированных последовательностей).

Ш>Задача -- красиво убить goto.

В код не вдумывался но от условия повеяло std::merge
... << RSDN@Home 1.1.4 stable rev. 510>>
Re[3]: Убить goto
От: Кодт Россия  
Дата: 16.02.06 15:54
Оценка:
Здравствуйте, night beast, Вы писали:

К>>Красиво, но несколько затратно (делаем лишние проверки).


NB>for ( ; ;) {
NB>   if ( !a ) { while(b) { fun(*b); ++b; } break; }
NB>   if ( !b ) { while(a) { fun(*a); ++a; } break; }

NB>   switch (...)
NB>}

Тоже неплохо. Кстати, всё равно есть лишние проверки.
Перекуём баги на фичи!
Re[4]: Убить goto
От: night beast СССР  
Дата: 16.02.06 16:56
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, night beast, Вы писали:


К>>>Красиво, но несколько затратно (делаем лишние проверки).


К>
NB>>for ( ; ;) {
NB>>   if ( !a ) { while(b) { fun(*b); ++b; } break; }
NB>>   if ( !b ) { while(a) { fun(*a); ++a; } break; }

NB>>   switch (...)
NB>>}
К>

К>Тоже неплохо. Кстати, всё равно есть лишние проверки.

никто и не спорит чисто субъективно -- все изменения в обном месте.

кстати, вспомнился занятный факт: continue в switch действует на внешний цикл.
таким образом, если в исходном тексте break заменить на continue, go to -- на break, и после switch
поставить break, то все должно работать.
не утверждаю, что это будет красивее
Re: Убить goto
От: Аноним  
Дата: 16.02.06 18:40
Оценка:
Если подразумевается классическое слияние то одной строчки не хватает:
Ш>       case CmpEqual :
Ш>        {
Ш>         fun(*a);
>>>>>>>>>>>>fun(*a);
Ш>         ++a;
Ш>         ++b;
             
Ш>         if( !a ) goto finish_b;
Ш>         if( !b ) goto finish_a;
Ш>        }  
Ш>      }  
...      
Ш>
Re[2]: Убить goto
От: Шахтер Интернет  
Дата: 17.02.06 09:26
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Если подразумевается классическое слияние то одной строчки не хватает:


Нет, строится объединения множеств. Результирующая выходная последовательность строго монотонная.
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[3]: Убить goto
От: kan_izh Великобритания  
Дата: 17.02.06 13:31
Оценка:
Шахтер wrote:

> А>Если подразумевается классическое слияние то одной строчки не хватает:

> Нет, строится объединения множеств. Результирующая выходная
> последовательность строго монотонная.

А чем std::set_union не устраивает? Там, кстати, нет goto (по крайней мере в MSVC7.1 имплементации).
Posted via RSDN NNTP Server 2.0
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[4]: Убить goto
От: Шахтер Интернет  
Дата: 17.02.06 13:46
Оценка:
Здравствуйте, kan_izh, Вы писали:

_>Шахтер wrote:


>> А>Если подразумевается классическое слияние то одной строчки не хватает:

>> Нет, строится объединения множеств. Результирующая выходная
>> последовательность строго монотонная.

_>А чем std::set_union не устраивает? Там, кстати, нет goto (по крайней мере в MSVC7.1 имплементации).


Этот вопрос оффтопик и вообще идиотский.
Не пробовал в автомобиль на бензиновом движке заливать диз-топливо?
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[2]: Убить goto
От: _JoKe_  
Дата: 17.02.06 15:40
Оценка:
Здравствуйте, Кодт, Вы писали:
К>Красиво, но несколько затратно (делаем лишние проверки).
К>
К>while(a && b)
К>{
К>  switch(Cmp(*a,*b))
К>  {
К>  case CmpLess:    fun(*a); ++a; break;
К>  case CmpEqual:   fun(*a); ++a; ++b; break;
К>  case CmpGreater: fun(*b); ++b; break;
К>  }
К>}
К>while(a) { fun(*a); ++a; }
К>while(b) { fun(*b); ++b; }
К>


небольшая коррекция для пущей красоты

switch(Cmp(*a,*b))
{
 case CmpEqual:   fun(*a); ++b;
 case CmpLess:    fun(*a); ++a; break;
 case CmpGreater: fun(*b); ++b; break;
}
... << RSDN@Home 1.1.4 @@subversion >>
Re[2]: Убить goto
От: Шахтер Интернет  
Дата: 20.02.06 08:06
Оценка:
Здравствуйте, Olegator, Вы писали:

O>Здравствуйте, Шахтер, Вы писали:


Ш>>Что-то много всякой фигнёй в последнее время страдаем (особенно философской).


Ш>>Вот фрагмент кода (слияние двух отсортированных последовательностей).

Ш>>Задача -- красиво убить goto.

O>А можно ли в объединяемые множества добавить по элементу? Если да, то нужно вставить в концы обеих последовательностей бесконечность.


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

Тем не менее -- засчитаю за решение.
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[2]: Убить goto
От: Шахтер Интернет  
Дата: 20.02.06 08:24
Оценка:
Здравствуйте, Olegator, Вы писали:

O>Здравствуйте, Шахтер, Вы писали:


Ш>>Что-то много всякой фигнёй в последнее время страдаем (особенно философской).


Ш>>Вот фрагмент кода (слияние двух отсортированных последовательностей).

Ш>>Задача -- красиво убить goto.

O>А можно ли в объединяемые множества добавить по элементу? Если да, то нужно вставить в концы обеих последовательностей бесконечность.


Можно ничего не вставлять, а использовать усовершенствованную функцию сравнения.

template <class Range>
CmpResult CmpFirstElement(Range a,Range b)
 {
  if( !a )
    {
     return (!b)?CmpEqual:CmpGreater;
    }

  if( !b ) return CmpLess;

  return Cmp(*a,*b);
 }


К сожалению, этот способ вносит ненужный оверхед тоже.
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[3]: Убить goto
От: _JoKe_  
Дата: 20.02.06 08:33
Оценка:
_JK>
_JK>switch(Cmp(*a,*b))
_JK>{
_JK> case CmpEqual:   /*fun(*a);*/ ++b;
_JK> case CmpLess:    fun(*a); ++a; break;
_JK> case CmpGreater: fun(*b); ++b; break;
_JK>}
_JK>


комент забыл поставить
... << RSDN@Home 1.1.4 @@subversion >>
Re[2]: Убить goto
От: Шахтер Интернет  
Дата: 20.02.06 13:37
Оценка:
Здравствуйте, Vain, Вы писали:

V>мож что-где упустил, но общий аргумент должен быть ясен.. Ж)


Упустил то, что невозможен двухуровневый break.
Тут правда можно использовать break; -- continue;


template <class Range> 
template <class Collector>
typename ResultAttributes<typename Collector::FunctorType>::ResultType 
 UnionGenType<Range>::operator () (Collector collector) const
 {
  Range a=a_,b=b_;
  
  typedef typename Collector::FunctorType FunctorType;
  
  FunctorType fun(collector);

  struct Finish
   {
    FunctorType &fun;

    Finish(FunctorType &fun_) : fun(fun_) {}

    void operator () (Range r)
     {  
      for(; +r ;++r) fun(*r);
     }
   } finish(fun);
  
  if( !a ) 
    {
     finish(b);
    }
  else if( !b ) 
    {
     finish(a);
    }
  else 
    for(;;)
      {
       switch( Cmp(*a,*b) )
         {
          case CmpLess :
           {
            fun(*a);
            ++a;
             
            if( +a ) continue;

            finish(b);
           }
          break;
           
          case CmpGreater :
           {
            fun(*b);
            ++b;
             
            if( +b ) continue;

            finish(a);
           }
          break;
           
          case CmpEqual :
           {
            fun(*a);
            ++a;
            ++b;
             
            if( +a )
              {
               if( +b ) continue;

               finish(a);
              }  
            else
              {
               finish(b);  
              }
           }  
          break;
         }

       break;
      }  
      
  return ResultAttributes<FunctorType>::GetResult(fun);
 }
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[3]: Убить goto
От: Cyberax Марс  
Дата: 20.02.06 13:57
Оценка:
Шахтер wrote:
> Упустил то, что невозможен двухуровневый break.
> Тут правда можно использовать break; -- continue;
По-моему, исходный вариант с goto был понятнее
Posted via RSDN NNTP Server 2.0
Sapienti sat!
Re[5]: Убить goto
От: night beast СССР  
Дата: 20.02.06 14:11
Оценка:
Здравствуйте, Шахтер, Вы писали:

Ш>Здравствуйте, Cyberax, Вы писали:


C>>Шахтер wrote:

>>> Упустил то, что невозможен двухуровневый break.
>>> Тут правда можно использовать break; -- continue;
C>>По-моему, исходный вариант с goto был понятнее

Ш>Дык о том и речь. Мне кажется, что данный пример демонстрирует вредность догм в программировании. Одна из таких догм -- не используй goto.

Ш>Обычно он не нужен. Но иногда его использование совершенно оправдано.

явно не этот случай
вариант Кодта вполне ничего.
Re[3]: Убить goto
От: Vain Россия google.ru
Дата: 20.02.06 17:08
Оценка:
Здравствуйте, Шахтер, Вы писали:

V>>мож что-где упустил, но общий аргумент должен быть ясен.. Ж)

Ш>Упустил то, что невозможен двухуровневый break.
а ну да, но не в этом суть.. Ж)
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re[6]: Убить goto
От: Шахтер Интернет  
Дата: 21.02.06 08:11
Оценка:
Здравствуйте, night beast, Вы писали:

NB>Здравствуйте, Шахтер, Вы писали:


Ш>>Здравствуйте, Cyberax, Вы писали:


C>>>Шахтер wrote:

>>>> Упустил то, что невозможен двухуровневый break.
>>>> Тут правда можно использовать break; -- continue;
C>>>По-моему, исходный вариант с goto был понятнее

Ш>>Дык о том и речь. Мне кажется, что данный пример демонстрирует вредность догм в программировании. Одна из таких догм -- не используй goto.

Ш>>Обычно он не нужен. Но иногда его использование совершенно оправдано.

NB>явно не этот случай

NB>вариант Кодта вполне ничего.

Он вводит лишние вычисления в код (либо лишние данные).
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[7]: Убить goto
От: night beast СССР  
Дата: 21.02.06 09:52
Оценка:
Здравствуйте, Шахтер, Вы писали:

Ш>Здравствуйте, night beast, Вы писали:


NB>>Здравствуйте, Шахтер, Вы писали:


Ш>>>Дык о том и речь. Мне кажется, что данный пример демонстрирует вредность догм в программировании. Одна из таких догм -- не используй goto.

Ш>>>Обычно он не нужен. Но иногда его использование совершенно оправдано.

NB>>явно не этот случай

NB>>вариант Кодта вполне ничего.

Ш>Он вводит лишние вычисления в код (либо лишние данные).


O(n)
это всего лишь показывает, что красивый код не всегда самый быстрый, и наоборот.
ничего личного, но меня твой исходный текст не впечатлил.
Re[9]: Дело вкуса.
От: Erop Россия  
Дата: 24.02.06 12:18
Оценка:
Здравствуйте, Шахтер, Вы писали:

Ш>Для меня красота в программировании -- это функциональность и экономность.

А "
Ш>дама, заросшая жиром, некрасива
" -- это нефункционально или неэкономно?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[3]: Убить goto
От: Андрей Тарасевич Беларусь  
Дата: 28.02.06 19:05
Оценка:
Здравствуйте, Шахтер, Вы писали:

А>>Если подразумевается классическое слияние то одной строчки не хватает:


Ш>Нет, строится объединения множеств. Результирующая выходная последовательность строго монотонная.


Так, так, так... Если предположить не строго монотонные входные последовательности, то этот алгоритм будет для каждой "постоянной" подпоследовательности выбирать более длинную (из присутствующих в двух входных массивах). Является ли это существенно частью спецификации? Или все таки можно сразу завязываться на тот факт, что входные последовательности строго монотонны. Если да, то это несколько меняет дело...
Best regards,
Андрей Тарасевич
Re[4]: Убить goto
От: Шахтер Интернет  
Дата: 03.03.06 21:18
Оценка:
Здравствуйте, Андрей Тарасевич, Вы писали:

АТ>Здравствуйте, Шахтер, Вы писали:


А>>>Если подразумевается классическое слияние то одной строчки не хватает:


Ш>>Нет, строится объединения множеств. Результирующая выходная последовательность строго монотонная.


АТ>Так, так, так... Если предположить не строго монотонные входные последовательности, то этот алгоритм будет для каждой "постоянной" подпоследовательности выбирать более длинную (из присутствующих в двух входных массивах). Является ли это существенно частью спецификации? Или все таки можно сразу завязываться на тот факт, что входные последовательности строго монотонны. Если да, то это несколько меняет дело...


Да, входные последовательности строго монотонны.
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[5]: Убить goto
От: Шахтер Интернет  
Дата: 03.03.06 21:33
Оценка:
Здравствуйте, Андрей Тарасевич, Вы писали:

АТ>Можно также сделать так


АТ>
АТ>do
АТ>{
АТ>  for (; a && (!b || Cmp(*a, *b) <= CmpEqual); ++a)
АТ>    fun(*a);

АТ>  for (; b && (!a || Cmp(*a, *b) > CmpEqual); ++b)
АТ>    fun(*b);

АТ>} while (a)
АТ>


В условиях цикла присутствуют !b и !a, которые являются инвариантами цикла.
Есть ещё один недостаток -- в начале цикл может быть холостым. После чего последует повторное сравнение.
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[6]: Убить goto
От: Андрей Тарасевич Беларусь  
Дата: 03.03.06 22:06
Оценка:
Здравствуйте, Шахтер, Вы писали:

Ш>Здравствуйте, Андрей Тарасевич, Вы писали:


АТ>>Можно также сделать так


АТ>>
АТ>>do
АТ>>{
АТ>>  for (; a && (!b || Cmp(*a, *b) <= CmpEqual); ++a)
АТ>>    fun(*a);

АТ>>  for (; b && (!a || Cmp(*a, *b) > CmpEqual); ++b)
АТ>>    fun(*b);

АТ>>} while (a)
АТ>>


Ш>В условиях цикла присутствуют !b и !a, которые являются инвариантами цикла.


Ну так я же сам прокомментировал это вариант, как просто попытку достичь самоцели: растворить обработку хвостов в основном цикле. В качестве "разумного" варианта предлагался только первый — со 'swap'.

Ш>Есть ещё один недостаток -- в начале цикл может быть холостым. После чего последует повторное сравнение.


Не совсем понимаю, о чем идет речь в этом случае.
Best regards,
Андрей Тарасевич
Re[7]: Убить goto
От: Шахтер Интернет  
Дата: 04.03.06 20:57
Оценка:
Здравствуйте, Андрей Тарасевич, Вы писали:

АТ>Ну так я же сам прокомментировал это вариант, как просто попытку достичь самоцели: растворить обработку хвостов в основном цикле. В качестве "разумного" варианта предлагался только первый — со 'swap'.


А, тогда понятно.

Ш>>Есть ещё один недостаток -- в начале цикл может быть холостым. После чего последует повторное сравнение.


АТ>Не совсем понимаю, о чем идет речь в этом случае.


О том, что если в первом цикле мы вычислили Cmp(*a,*b) и получили >0, то мы этот цикл закончим и плавно войдем во второй, где снова вычислим это же выражение и получим тот же результат (фактически уже известный). Избыточное телодвижение. То же самое будет при переходе снизу вверх.
Если это была бы одиночная избыточность, это было бы ещё ничего, но постоянные повторения в цикле -- слишком жирно.
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re: Убить goto
От: IROV..  
Дата: 30.03.06 20:50
Оценка:
Здравствуйте, Шахтер, Вы писали:


template <class Range> 
template <class Collector>
typename ResultAttributes<typename Collector::FunctorType>::ResultType 
UnionGenType<Range>::operator () (Collector collector) const
{
    Range a=a_,b=b_;

    typedef typename Collector::FunctorType FunctorType;

    FunctorType fun(collector);

    //////////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////////////
    struct s_finish_a
    {
        finish_a(Range &_a, FunctorType &_fun)
            :a(_a)
            ,fun(_fun)
        {
        }

        void build()
        {
            for(; +a ;++a) fun(*a);
        }

        typename ResultAttributes<typename Collector::FunctorType>::ResultType get_result()
        {
             build();

             return ResultAttributes<FunctorType>::GetResult(fun);
        }

        Range &a;
        FunctorType &fun;
    };

    //////////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////////////
    struct s_finish_b
        : public s_finish_a
    {
        finish_a(Range &_a,Range &_b, FunctorType &_fun)
            :finish_a(_a,_fun)
            ,b(_b)
        {
        }

        typename ResultAttributes<typename Collector::FunctorType>::ResultType get_result()
        {
            build();

            for(; +b ;++b) fun(*b);

            return ResultAttributes<FunctorType>::GetResult(fun)
        }

        Range &b;
    };

    s_finish_a finish_a(a,fun);
    s_finish_b finish_b(a,b,fun);

    //////////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////////////

    if( !a ) return finish_b.get_result();
    if( !b ) return finish_a.get_result();

    for(;;)
        switch( Cmp(*a,*b) )
    {
        case CmpLess :
            {
                fun(*a);
                ++a;

                if( !a ) return finish_b.get_result();
            }
            break;

        case CmpGreater :
            {
                fun(*b);
                ++b;

                if( !b ) return finish_a.get_result();
            }
            break;

        case CmpEqual :
            {
                fun(*a);
                ++a;
                ++b;

                if( !a ) return finish_b.get_result();
                if( !b ) return finish_a.get_result();
            }  
    }  

    return finish_b.get_result();
}
я не волшебник, я только учусь!
Re[5]: Убить goto
От: Аноним  
Дата: 31.03.06 04:43
Оценка:
Здравствуйте, Шахтер, Вы писали:

Ш>Здравствуйте, Cyberax, Вы писали:


C>>Шахтер wrote:

>>> Упустил то, что невозможен двухуровневый break.
>>> Тут правда можно использовать break; -- continue;
C>>По-моему, исходный вариант с goto был понятнее

Ш>Дык о том и речь. Мне кажется, что данный пример демонстрирует вредность догм в программировании. Одна из таких догм -- не используй goto.

Ш>Обычно он не нужен. Но иногда его использование совершенно оправдано.
Не буду вдаваться в тонкости, но чем вас не устраивает такой код на пседоязыке:
while ((!A)&&(!B)) {
  if (A < B) {
    C = A;
    nextC; nextA;
  }
  else {
    C = B;
    nextC; nextB;
  }
}
while (!A) {
  C = A;
  nextC; nextA;
}
while (!B) {
  C = B;
  nextC; nextB;
}

По-моему очень даже внятный код!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.