الگوریتم جابه‌جایی یای انحصاری

الگوریتم جابه‌جایی یای انحصاری، الگوریتمی است که با استفاده از عملگر بیتی یای انحصاری مقدار دو متغیر را بدون استفاده از متغیر دیگری یا تغییر نوع متغیرها با یکدیگر جابه‌جا می‌کند.

الگوریتم

الگوریتم به شرح زیر است:
X := X XOR Y
Y := Y XOR X
X := X XOR Y
این الگوریتم معادل ۳ دستور در زبان ماشین است. همچنین چون یای انحصاری خاصیت جابه‌جایی دارد، دو عبارت X XOR Y و Y XOR X برابرند.
این الگوریتم در حالتی که دو متغیر X و Y برابر باشند (منظور از برابری دو متغیر، یکی بودن آدرس آن‌هاست نه یکی بودن مقادیر آن‌ها)، به درستی کار نمی‌کند زیرا پس از خط اول مقدار X برابر ۰ شده و چون آدرس X و Y یکی است، مقدار Y هم برابر ۰ می‌شود و دو متغیر مقادیر واقعی خود را از دست می‌دهند.

با استفاده از جبر خطی

یای انحصاری را می‌توان به عنوان جمع دودویی و ۲ بیت را به عنوان یک بردار در میدان ۲ در نظر گرفت. در این‌صورت الگوریتم را می‌توان با ضرب یک ماتریس ۲ ۲ در میدان ۲ معادل کرد. برای سادگی فرض می‌کنیم X و Y یک بیت باشند. در این‌صورت مرحله اول الگوریتم معادل خواهدبود با:
X := X XOR Y
Y := Y
که معادل ماتریسی آن است. داریم:
دنباله دستورات الگوریتم را می‌توان به صورت ضرب ماتریس‌های ۲ ۲ نشان داد:
(چون جمع در میدان ۲ است، ۰ = ۱ + ۱)
برای تعمیم به وقتی که X و Y برادارهای بیتی به طول n اند، یای انحصاری معادل ماتریس ۲n ۲n است. باید توجه کرد که این ماتریس بر روی متغیرها (که در حافظه آدرس دارند) اعمال نمی‌شوند بلکه بر روی مقادیر اعمال می‌شوند.

نمونه کد

کد زیر، کد الگوریتم به زبان C است:
1  void xorSwap (int *x, int *y)2  {3      if (x != y)4      {5          *x ^= *y;6          *y ^= *x;7          *x ^= *y;8      }9  }
باید توجه‌کرد که کد ابتدا بررسی می‌کند که آیا آدرس دو متغیر یکی است یا خیر زیرا اگر یکی باشد، همان‌گونه که پیش از این گفته‌شد مقدار متغیر ۰ خواهدشد. همچنین می‌توان الگوریتم را به صورت یک ماکرو تعریف کرد:
#define XORSWAP_UNSAFE(a, b) ((a)^=(b),(b)^=(a),(a)^=(b))/* درصورتی که دو متغیر برابر باشند، به درستی کار نمی‌کند. */#define XORSWAP(a, b)   ((&(a) == (b)) ? (a) : ((a)^=(b),(b)^=(a),(a)^=(b)))/* ابتدا یکی نبودن آدرس‌ها را بررسی می‌کند، سپس دو متغیر را جابه‌جا می‌کند. */

دلایل عدم استفاده از الگوریتم

بیشتر کامپایلرهای جدید متغیرهای موقت را پس از استفاده، آزاد می‌کنند لذا از نظر حافظه و زمان الگوریتم جابه‌جایی سه طرفه با این الگوریتم تفاوتی ندارد. ضمن آنکه این الگوریتم برای کسی که با روش آن آشنا نباشد نامفهوم است.
در کامپوترهای جدید، الگوریتم جابه‌جایی یای انحصاری از الگوریتم جابه‌جایی سه طرفه کنتر است. از پردازنده‌های x۸۶ اینتل و ای‌ام‌دی به بعد، جابه‌جایی بین ثبات‌ها بدون تأخیر انجام می‌شود. حتی اگر ثباتی برای استفاده نباشد، دستور XCHG حداقل به اندازه سه عملیات یای انحصاری سریع خواهدبود. دلیل دیگر آن است که پردازنده‌ها حتی‌الامکان دستورات را موازی اجرا می‌کنند. در الگوریتم یای انحصاری، ورودی‌های هر عملگر به خروجی مرحله قبل بستگی دارد لذا نمی‌توان مراحل آن را موازی اجرا کرد.

تعمیم به دیگر عملگرها

در این الگوریتم، یای انحصاری می‌تواند با هر عملگری که ۴ خاصیت گفته‌شده را داشته‌باشد، جایگزین شود. با جایگزین کردن یای انحصاری با جمع و تفریق خواهیم‌داشت:
1 void addSwap (unsigned int *x, unsigned int *y)2  {3      if (x != y)4      {5          *x = *x + *y;6          *y = *x - *y;7          *x = *x - *y;8      }9  }
برخلاف یای انحصاری، در این نوع پردازنده یا زبان برنامه‌نویسی استفاده‌شده باید از هم‌نهشتی یا اعداد بزرگ استفاده کنند تا بتوان مطمئن شد که عملگرها سرریز ندارند؛ لذا کاربرد این از کاربرد یای انحصاری کمتر خواهدبود.