Недавно я столкнулся с этим вопросом написать функцию для замены двух чисел без использования дополнительного пространства. Функция может быть двумя способами:
int swap ( int *a, int* b)
{
*a = *a+*b;
*b = *a-*b;
*a = *a-*b;
}
Другим способом является операция XOR:
int swap ( int *a, int* b)
{
*a = *a^*b;
*b = *a^*b;
*a = *a^*b;
}
Несмотря на то, что обе эти функции являются хорошей идеей, они не будут работать, если оба а и b указывают на одну ячейку памяти? Как справиться с этим?
Проблема очевидна в математике.
int swap ( int *a, int* b)
{
*a = *a+*b;
*b = *a-*b;
*a = *a-*b;
}
когда a
и b
указывают на то же место, тогда код выше превращается в
*a = *a + *a; // *a = 2 x (*a)
*b = *a - *a; // = 0
*a = *a - *a; // = 0
Итак, оба *a
и *b
равны нулю. Для этого вы должны обращаться с помощью if
:
int swap ( int *a, int* b)
{
if (a!=b)
{
*a = *a+*b;
*b = *a-*b;
*a = *a-*b;
}
}
И то же самое для версии xor
.
#define SWAP(a, b) (((a) == (b)) || (((a) ^= (b)), ((b) ^= (a)), ((a) ^= (b))))
a
и b
не оригинальные указатели.
Почему бы кто-нибудь обменять два числа, не используя лишнее пространство?
Какой садист даст вам достаточно места для двух, но не трех?
Почему вы так называете это "космос"? Это всего лишь третье число, нет необходимости ссылаться на огромное, заполненное вакуумом место.
Алгоритм, использующий временное использование O (1) пространства в количестве операций свопинга. Это O (n) в длине числа, но вполне возможно, что бит-twiddling и арифметические придают процессор-недружественный n.
Если у вас недостаточно места для простого номера, вы просто исчерпали пространство. Я не могу видеть, где вы можете перейти от свопа в этом случае.
Почему бы не сохранить эти два номера в их собственных местах в первую очередь?
Вы можете попробовать это, а = а + Ь; B = A-B; а = а-б;
if (a != b)
??