LINUX.ORG.RU
ФорумTalks

Квиз (не пользоваться гуглом)


0

1

Задачка старая и известная, просто интересно посмотреть, сколько людей на нее сейчас тут сходу ответят. Вот она:

Пусть есть две переменные, скажем

int a = 10, b = 5;
Поменять их значения местами, не создавая новую переменную.

Deleted

Последнее исправление: Deleted (всего исправлений: 2)
Ответ на: комментарий от drBatty

наглое 4.2

#include <cstdio>

int main()
{
	int a = 10;
	int b = 5;
	int *pa = &a;
	int *pb = &b;
	int *tmp = pa;
	pa = pb;
	pb = tmp;
	printf("a=%d b=%d\n", a, b);
}

┌[~/apps/cpp]
└> g++ r.cpp 
┌[~/apps/cpp]
└> ./a.out 
a=10 b=5
nanoolinux ★★★★
()

(придумал не я, я только воспроизвожу по памяти, узнал про способ давно)

a = a + b
b = a - b
a = a - b

Ttt ☆☆☆☆☆
()
Ответ на: комментарий от drBatty

Можно сюда прикрутить подобие александресковских TypeList'ов и делать static assert, если тип не в списке.

DELIRIUM ☆☆☆☆☆
()

swap(a,b);

В области видимости новой переменной нет.

record ★★★★★
()
Последнее исправление: record (всего исправлений: 1)
Ответ на: комментарий от lazyklimm

int a = 10, b = 5;

переполнение

прикупи памяти, нищеброд

zolden ★★★★★
()
Ответ на: комментарий от qnikst

и?

И функциональный язык скрывает возможности аппаратуры. Вот если бы этот код выполнялся на машине Dataflow архитектуры...

AptGet ★★★
()
Ответ на: комментарий от qnikst

Все скрывает. Но императивщина таки слабее абстрагирована от фон Неймановских машин.

AptGet ★★★
()

Любителей ad-hoc решений тред.

buddhist ★★★★★
()
Ответ на: комментарий от Deleted

Ну да, проверяем качество нынешнего образования.

«Мы, в свое время, многое делали через жопу. Посмотрим может ли современная молодежь делать через жопу не меньше чем мы».

r ★★★★★
()

Как насчет записать их значения в файл?

Vekt
()
Ответ на: комментарий от bhfq

Фу

Лучше конечно заморачиваться с вычислениями, чем написать одну строчку.

J ★★★★★
()
Ответ на: комментарий от z00ke

И я о том же, только чтобы потоки по ядрам разбрасывались в соответствии с нагрузкой. А то недалеко до переполнения :)

Xenesz ★★★★
()

=)

Пусть есть две переменные, скажем

int a = 10, b = 5;
Поменять их значения местами, не создавая новую переменную.

Да легко:

a = 5;
b = 10;

Deleted
()

Это даже в школе объясняют. Шёл бы ты отсюда.

CYB3R ★★★★★
()

a=a+b;
b=a-b;
a=a-b;
И да, сейчас время выполнения программы (алгоритма) куда важнее, чем выделяемая им память.

comp00 ★★★★
()

архитектурно зависимо, но

*(uint64_t *)&b=((uint64_t)b<<32)|a;

MKuznetsov ★★★★★
()

int a = 10, b = 5;
Поменять их значения местами, не создавая новую переменную

а=5;b=10;

ymuv ★★★★
()

a = a + b;
b = a - b;
a = a - b;


Точно также можно xor'ом,

evilface ★★
()

Подкину задачку поинтереснее: вычислить минимум из двух положительных 32разрядных чисел, используя бинарные операции +,-,*, знаковый div, беззнаковый div, and, or, xor, andn, orn, xorn, shl, shr со сдвигом знакового бита и без.

Я нашел способ с 4 операциями.

fads ★★
()

Поменять их значения местами, не создавая новую переменную.

push a
push b
pop a
pop b

PA
()
a ^= b;
b ^= a;
a ^= b;
Deleted
()
Ответ на: комментарий от Deleted

Если оператор =() не переопределен руками, он должен вызывать конструктор копирования, создавать новый объект, являющийся копией присваиваемого, а затем помещать его в память на место того, который стоит в присваивании слева.

да? а я всегда думал, что неопределённый operator= тупо копирует побайтно один класс в другой.

drBatty ★★
()
Ответ на: комментарий от drBatty

именно так, инфа 100%. другое дело что если конструктор копирования тоже не определен, тогда вызывается конструктор копирования по умолчанию, который как раз тупо копирует побайтно один объект в другой.

Deleted
()
Ответ на: комментарий от comp00

a=a+b;b=a-b;a=a-b;И да, сейчас время выполнения программы (алгоритма) куда важнее, чем выделяемая им память.

и да, на кой хрен тут нужно ещё одно аналогичное решение? разве непонятно, что тут достаточно одной операции, и ещё двух обратных к ней? Ну или трёх операций XOR, которая обратна к самой себе?

И да, выделяемая память тоже играет роль. И сегодня тоже. Всё зависит от задачи. Как тебе такое решение:

1. создаём таблицу

a[0x0000]=0x0000;
a[0x0001]=0x0100;
...
a[0x050a]=0x0a05;

2. а теперь

unsigned *p = &a[(a << 8) | b];
a = *p >> 8;
b = *p & 0xff;

подумаешь... Всего 65536 байт для обмена двух любых байт местами. Память не играет роли.

drBatty ★★
()
Ответ на: комментарий от Deleted

я _всегда_ определяю конструктор копирования и operator=(). Что-бы не путаться. Если не знаю как, определяю пустой private.

drBatty ★★
()
Ответ на: комментарий от derlafff

Ну или на православном си:

  a += b; b = a - b; a -= b;

//тред не читал, написал сейчас сам

derlafff ★★★★★
()
Последнее исправление: derlafff (всего исправлений: 1)
Ответ на: комментарий от drBatty

и да, на кой хрен тут нужно ещё одно аналогичное решение?

ТС спросил — я ответил, и тред не читал как всегда

разве непонятно, что тут достаточно одной операции, и ещё двух обратных к ней?

а я что по твоему привел?

И да, выделяемая память тоже играет роль. И сегодня тоже. Всё зависит от задачи. Как тебе такое решение:

Теперь представь, что ты сортируешь массив из овер 100к элементов типа long long int.... Лучше один раз выделить, пусть даже 500Кбайта, память, чем в цикле каждый раз вычислять. И это самый простой пример.

Всего 65536 байт для обмена двух любых байт местами. Память не играет роли.

Не надо утрировать. На первом курсе алгоритмов учат выбирать оптимальный алгоритм для каждой задачи.

comp00 ★★★★
()
Ответ на: комментарий от comp00

а я что по твоему привел?

а сложно догадаться, что таких тут Over9000? С первого поста ЧСХ.

Теперь представь, что ты сортируешь массив из овер 100к элементов типа long long int.... Лучше один раз выделить, пусть даже 500Кбайта, память, чем в цикле каждый раз вычислять. И это самый простой пример.

причём тут сортировка? откуда 500К?

Не надо утрировать. На первом курсе алгоритмов учат выбирать оптимальный алгоритм для каждой задачи.

хреново учат. И я не утрирую.

drBatty ★★
()
Ответ на: комментарий от drBatty

а сложно догадаться, что таких тут Over9000?

зачем что-то гадать? ТС спросил, я написал, я даже не видел что здесь за 2 страницы перевалило.

причём тут сортировка?

В большинстве сортировок необходимо менять элементы местами, кэп.

откуда 500К?

число из головы.

хреново учат. И я не утрирую.

Утрируешь . Действительно, для простой программы в который просто требуется поменять местами 2 числа, 65кб слишком жирно. Но я привел пример, где лучше затратить некий объем памяти, чем увеличить время выполнения алгоритма чуть ли не в разы.

comp00 ★★★★
()
Ответ на: комментарий от comp00

В большинстве сортировок необходимо менять элементы местами, кэп.

задача из первого поста явно не про сортировку на месте. Имея в памяти массив на 500 элементов глупо ограничивать выделение 4х или 8и байтов. В любом случае, часто есть смысл менять местами вовсе не значения, а указатели на них, как я писал выше.

Утрируешь . Действительно, для простой программы в который просто требуется поменять местами 2 числа, 65кб слишком жирно.

кто сказал, что там 2 числа? Возможно их 100500. Но и в этом случае такой алгоритм не эффективен.

Но я привел пример, где лучше затратить некий объем памяти, чем увеличить время выполнения алгоритма чуть ли не в разы.

сортировка 500К целых? алгоритмы типа a ^= b; b ^= a; a ^= b; будут медленнее, чем простой обмен, через временную переменную.

Кроме того, в a ^= b; b ^= a; a ^= b; временная переменная всё равно есть, только она от нас скрыта синтаксическим сахаром. Во всяком случае, в x86 такие операции невозможны в оперативной памяти.

drBatty ★★
()
Ответ на: комментарий от drBatty

задача из первого поста явно не про сортировку на месте.

Задача чисто теоретическая. Точнее, даже не задача. Типа а знаете ли вы, ответ на школьную задачку?

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

Указатели — это хорошо, вот только не во всех языках они есть.

кто сказал, что там 2 числа?

Прочти шапку треда. Внимательно. Не волнуйся и не спеши.

Пусть есть две переменные,

алгоритмы типа a ^= b; b ^= a; a ^= b; будут медленнее, чем простой обмен, через временную переменную.

А теперь, цитата из моего первого поста в этом треде

И да, сейчас время выполнения программы (алгоритма) куда важнее, чем выделяемая им память.

и

Лучше один раз выделить, пусть даже 500Кбайта, память, чем в цикле каждый раз вычислять. И это самый простой пример.

Объяснения очевидных вещей не делает человека умным. Просто, на будущее.

comp00 ★★★★
()
Ответ на: комментарий от comp00

Задача чисто теоретическая. Точнее, даже не задача. Типа а знаете ли вы, ответ на школьную задачку?

именно так. Типа «не пользуясь гуглом скажите, сколько будет 2*2=? (умножение запрещено использовать)». И понимай как знаешь...

Указатели — это хорошо, вот только не во всех языках они есть.

мне не нужны именно указатели. Достаточно как-либо переименовать переменные. Например в пайтоне a, b = b, a или в x86 асме xchg eax, edx (тут тоже регистр известный как eax становится известным как edx и наоборот)

Прочти шапку треда. Внимательно. Не волнуйся и не спеши.

пофиг до шапки, я про твой пост. Почему ты от балды берёшь 500К, а я не могу взять 100500?

И да, сейчас время выполнения программы (алгоритма) куда важнее, чем выделяемая им память. (*)

и

Лучше один раз выделить, пусть даже 500Кбайта, память, чем в цикле каждый раз вычислять. И это самый простой пример.

Объяснения очевидных вещей не делает человека умным. Просто, на будущее.

это ты про себя? так вот, высказывание (*) далеко не очевидно. Даже сегодня. Особенно учитывая тот факт, что время работы алгоритма сегодня напрямую зависит от того, влезут или не влезут его данные в кеш? И если влезут, то в кеш какого уровня? Потому, сложные алгоритмы с разнообразными таблицами работают сегодня медленнее, чем более простые, которые используют больше простых вычислений без всяких таблиц. И это не смотря на то, что сложным табличным алгоритмам нужно выполнять намного меньше операций. Т.е. сегодня в разы быстрее например просчитать 1000 синусов, чем тащить за собой таблицу, из которой можно «мгновенно» извлечь нужный сейчас синус. Я уж не говорю про примитивные операции типа обмена или там умножения. Проблема в том, что многие программисты сейчас считают время неправильно - сотня операций над регистрами сейчас может занимать намного меньше времени, чем одна операция над полем памяти в сотню значений.

drBatty ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.