К>Тоже неплохо. Кстати, всё равно есть лишние проверки.
никто и не спорит чисто субъективно -- все изменения в обном месте.
кстати, вспомнился занятный факт: continue в switch действует на внешний цикл.
таким образом, если в исходном тексте break заменить на continue, go to -- на break, и после switch
поставить break, то все должно работать.
не утверждаю, что это будет красивее
Re: Убить goto
От:
Аноним
Дата:
16.02.06 18:40
Оценка:
Если подразумевается классическое слияние то одной строчки не хватает:
Шахтер wrote:
> А>Если подразумевается классическое слияние то одной строчки не хватает: > Нет, строится объединения множеств. Результирующая выходная > последовательность строго монотонная.
А чем std::set_union не устраивает? Там, кстати, нет goto (по крайней мере в MSVC7.1 имплементации).
Posted via RSDN NNTP Server 2.0
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, kan_izh, Вы писали:
_>Шахтер wrote:
>> А>Если подразумевается классическое слияние то одной строчки не хватает: >> Нет, строится объединения множеств. Результирующая выходная >> последовательность строго монотонная.
_>А чем std::set_union не устраивает? Там, кстати, нет goto (по крайней мере в MSVC7.1 имплементации).
Этот вопрос оффтопик и вообще идиотский.
Не пробовал в автомобиль на бензиновом движке заливать диз-топливо?
Шахтер wrote:
>> > А>Если подразумевается классическое слияние то одной строчки не хватает: >> > Нет, строится объединения множеств. Результирующая выходная >> > последовательность строго монотонная. > _>А чем std::set_union не устраивает? Там, кстати, нет goto (по крайней > мере в MSVC7.1 имплементации). > Этот вопрос оффтопик и вообще идиотский. > Не пробовал в автомобиль на бензиновом движке заливать диз-топливо?
Если говорить метафорами, то твой вопрос выглядит "Я вот тут изобрёл велосипед, но колесо квадратное. Кто сможет
выпрямить?". Я лишь порекомендовал взглянуть на уже готовый. Не устраивает, так не устраивает, но хоть посмтотри как
круглые колёса делаются.
Posted via RSDN NNTP Server 2.0
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, Шахтер, Вы писали:
Ш>Что-то много всякой фигнёй в последнее время страдаем (особенно философской).
Ш>Вот фрагмент кода (слияние двух отсортированных последовательностей). Ш>Задача -- красиво убить goto.
А можно ли в объединяемые множества добавить по элементу? Если да, то нужно вставить в концы обеих последовательностей бесконечность.
Здравствуйте, Olegator, Вы писали:
O>Здравствуйте, Шахтер, Вы писали:
Ш>>Что-то много всякой фигнёй в последнее время страдаем (особенно философской).
Ш>>Вот фрагмент кода (слияние двух отсортированных последовательностей). Ш>>Задача -- красиво убить goto.
O>А можно ли в объединяемые множества добавить по элементу? Если да, то нужно вставить в концы обеих последовательностей бесконечность.
Мысль красивая. Но, боюсь, что не реализуемая, поскольку бесконечное значение не предусмотрено в тех типах, которые используются с этим шаблоном.
Здравствуйте, Olegator, Вы писали:
O>Здравствуйте, Шахтер, Вы писали:
Ш>>Что-то много всякой фигнёй в последнее время страдаем (особенно философской).
Ш>>Вот фрагмент кода (слияние двух отсортированных последовательностей). Ш>>Задача -- красиво убить goto.
O>А можно ли в объединяемые множества добавить по элементу? Если да, то нужно вставить в концы обеих последовательностей бесконечность.
Можно ничего не вставлять, а использовать усовершенствованную функцию сравнения.
Здравствуйте, Шахтер, Вы писали:
Ш>Что-то много всякой фигнёй в последнее время страдаем (особенно философской).
Ш>Вот фрагмент кода (слияние двух отсортированных последовательностей). Ш>Задача -- красиво убить goto.
Шахтер wrote: > Упустил то, что невозможен двухуровневый break. > Тут правда можно использовать break; -- continue;
По-моему, исходный вариант с goto был понятнее
Здравствуйте, Cyberax, Вы писали:
C>Шахтер wrote: >> Упустил то, что невозможен двухуровневый break. >> Тут правда можно использовать break; -- continue; C>По-моему, исходный вариант с goto был понятнее
Дык о том и речь. Мне кажется, что данный пример демонстрирует вредность догм в программировании. Одна из таких догм -- не используй goto. Обычно он не нужен. Но иногда его использование совершенно оправдано.
Здравствуйте, Шахтер, Вы писали:
Ш>Здравствуйте, Cyberax, Вы писали:
C>>Шахтер wrote: >>> Упустил то, что невозможен двухуровневый break. >>> Тут правда можно использовать break; -- continue; C>>По-моему, исходный вариант с goto был понятнее
Ш>Дык о том и речь. Мне кажется, что данный пример демонстрирует вредность догм в программировании. Одна из таких догм -- не используй goto. Ш>Обычно он не нужен. Но иногда его использование совершенно оправдано.
Здравствуйте, Шахтер, Вы писали:
V>>мож что-где упустил, но общий аргумент должен быть ясен.. Ж) Ш>Упустил то, что невозможен двухуровневый break.
а ну да, но не в этом суть.. Ж)
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Здравствуйте, night beast, Вы писали:
NB>Здравствуйте, Шахтер, Вы писали:
Ш>>Здравствуйте, Cyberax, Вы писали:
C>>>Шахтер wrote: >>>> Упустил то, что невозможен двухуровневый break. >>>> Тут правда можно использовать break; -- continue; C>>>По-моему, исходный вариант с goto был понятнее
Ш>>Дык о том и речь. Мне кажется, что данный пример демонстрирует вредность догм в программировании. Одна из таких догм -- не используй goto. Ш>>Обычно он не нужен. Но иногда его использование совершенно оправдано.
NB>явно не этот случай NB>вариант Кодта вполне ничего.
Он вводит лишние вычисления в код (либо лишние данные).
Здравствуйте, Шахтер, Вы писали:
Ш>Здравствуйте, night beast, Вы писали:
NB>>Здравствуйте, Шахтер, Вы писали:
Ш>>>Дык о том и речь. Мне кажется, что данный пример демонстрирует вредность догм в программировании. Одна из таких догм -- не используй goto. Ш>>>Обычно он не нужен. Но иногда его использование совершенно оправдано.
NB>>явно не этот случай NB>>вариант Кодта вполне ничего.
Ш>Он вводит лишние вычисления в код (либо лишние данные).
O(n)
это всего лишь показывает, что красивый код не всегда самый быстрый, и наоборот.
ничего личного, но меня твой исходный текст не впечатлил.
Здравствуйте, night beast, Вы писали:
NB>это всего лишь показывает, что красивый код не всегда самый быстрый, и наоборот.
Для меня красота в программировании -- это функциональность и экономность.
Так же как и в жизни -- дама, заросшая жиром, некрасива.
Но это, конечно, дело вкуса.
Здравствуйте, Шахтер, Вы писали:
Ш>Для меня красота в программировании -- это функциональность и экономность.
А " Ш>дама, заросшая жиром, некрасива
" -- это нефункционально или неэкономно?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, Шахтер, Вы писали:
Ш>>Для меня красота в программировании -- это функциональность и экономность. E>А " Ш>>дама, заросшая жиром, некрасива E>" -- это нефункционально или неэкономно?
Здравствуйте, Шахтер, Вы писали:
А>>Если подразумевается классическое слияние то одной строчки не хватает:
Ш>Нет, строится объединения множеств. Результирующая выходная последовательность строго монотонная.
Так, так, так... Если предположить не строго монотонные входные последовательности, то этот алгоритм будет для каждой "постоянной" подпоследовательности выбирать более длинную (из присутствующих в двух входных массивах). Является ли это существенно частью спецификации? Или все таки можно сразу завязываться на тот факт, что входные последовательности строго монотонны. Если да, то это несколько меняет дело...
Здравствуйте, Андрей Тарасевич, Вы писали:
А>>>Если подразумевается классическое слияние то одной строчки не хватает:
Ш>>Нет, строится объединения множеств. Результирующая выходная последовательность строго монотонная.
АТ>Так, так, так... Если предположить не строго монотонные входные последовательности, то этот алгоритм будет для каждой "постоянной" подпоследовательности выбирать более длинную (из присутствующих в двух входных массивах). Является ли это существенно частью спецификации? Или все таки можно сразу завязываться на тот факт, что входные последовательности строго монотонны. Если да, то это несколько меняет дело...
При наличии такой гарантии можно предложить следующий вариант (предполагая, что значения '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
Здравствуйте, Андрей Тарасевич, Вы писали:
АТ>Здравствуйте, Шахтер, Вы писали:
А>>>Если подразумевается классическое слияние то одной строчки не хватает:
Ш>>Нет, строится объединения множеств. Результирующая выходная последовательность строго монотонная.
АТ>Так, так, так... Если предположить не строго монотонные входные последовательности, то этот алгоритм будет для каждой "постоянной" подпоследовательности выбирать более длинную (из присутствующих в двух входных массивах). Является ли это существенно частью спецификации? Или все таки можно сразу завязываться на тот факт, что входные последовательности строго монотонны. Если да, то это несколько меняет дело...
Здравствуйте, Андрей Тарасевич, Вы писали:
АТ>Можно также сделать так
АТ>
АТ>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, которые являются инвариантами цикла.
Есть ещё один недостаток -- в начале цикл может быть холостым. После чего последует повторное сравнение.
Здравствуйте, Шахтер, Вы писали:
Ш>Здравствуйте, Андрей Тарасевич, Вы писали:
АТ>>Можно также сделать так
АТ>>
АТ>>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'.
Ш>Есть ещё один недостаток -- в начале цикл может быть холостым. После чего последует повторное сравнение.
Здравствуйте, Андрей Тарасевич, Вы писали:
АТ>Ну так я же сам прокомментировал это вариант, как просто попытку достичь самоцели: растворить обработку хвостов в основном цикле. В качестве "разумного" варианта предлагался только первый — со 'swap'.
А, тогда понятно.
Ш>>Есть ещё один недостаток -- в начале цикл может быть холостым. После чего последует повторное сравнение.
АТ>Не совсем понимаю, о чем идет речь в этом случае.
О том, что если в первом цикле мы вычислили Cmp(*a,*b) и получили >0, то мы этот цикл закончим и плавно войдем во второй, где снова вычислим это же выражение и получим тот же результат (фактически уже известный). Избыточное телодвижение. То же самое будет при переходе снизу вверх.
Если это была бы одиночная избыточность, это было бы ещё ничего, но постоянные повторения в цикле -- слишком жирно.
Здравствуйте, Шахтер, Вы писали:
Ш>Здравствуйте, 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;
}