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[8]: Убить goto
От: Шахтер Интернет  
Дата: 21.02.06 10:33
Оценка: :)
Здравствуйте, night beast, Вы писали:

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


Для меня красота в программировании -- это функциональность и экономность.
Так же как и в жизни -- дама, заросшая жиром, некрасива.
Но это, конечно, дело вкуса.
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[9]: Дело вкуса.
От: Erop Россия  
Дата: 24.02.06 12:18
Оценка:
Здравствуйте, Шахтер, Вы писали:

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

А "
Ш>дама, заросшая жиром, некрасива
" -- это нефункционально или неэкономно?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[10]: Дело вкуса.
От: Шахтер Интернет  
Дата: 24.02.06 15:31
Оценка: +1 :)
Здравствуйте, Erop, Вы писали:

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


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

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

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

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


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


Так, так, так... Если предположить не строго монотонные входные последовательности, то этот алгоритм будет для каждой "постоянной" подпоследовательности выбирать более длинную (из присутствующих в двух входных массивах). Является ли это существенно частью спецификации? Или все таки можно сразу завязываться на тот факт, что входные последовательности строго монотонны. Если да, то это несколько меняет дело...
Best regards,
Андрей Тарасевич
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[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: Убить goto
От: mcf  
Дата: 03.03.06 23:23
Оценка: -1
Здравствуйте, Шахтер, Вы писали:

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


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

Решение — заменить финиш а, финиш Бэ на функции и не париться, лучшего решения нет. Учим матчасть.
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...
Пока на собственное сообщение не было ответов, его можно удалить.