تبديل البتات في عدد معين

من موسوعة حسوب
< Algorithms
مراجعة 13:27، 29 نوفمبر 2019 بواسطة Mohammed Taher (نقاش | مساهمات) (أنشأ الصفحة ب'<noinclude>{{DISPLAYTITLE:تبديل البتات في عدد معين }}</noinclude> تبدّل هذه الخوارزمية بين موقعين (من الجانب ال...')
(فرق) → مراجعة أقدم | المراجعة الحالية (فرق) | مراجعة أحدث ← (فرق)
اذهب إلى التنقل اذهب إلى البحث

تبدّل هذه الخوارزمية بين موقعين (من الجانب الأيمن) في التمثيل البياني للعدد المعطى بشرط عدم حصول تداخل بين مجموعتي البتات، ثم تعيد النتيجة.

مثال:
المدخلات:

x = 47 (00101111)
p1 = 1 (البدء من البت الثاني من جهة اليمين)
p2 = 5 (البدء من البت السادس من جهة اليمين)
n = 3 (عدد البتات التي سيجري تبديلها)
المخرجات:
227 (11100011)

جرى تبديل ثلاثة بتات بدءًا من البت الثاني (من جهة اليمين) مع ثلاثة بتات بدءًا من البت السادس (من جهة اليمين).

مثال:

المدخلات:
x = 28 (11100)
p1 = 0 (البدء من البت الأول من جهة اليمين)
p2 = 3 (البدء من البت الرابع من جهة اليمين)
n = 2 (عدد البتات التي سيجري تبديلها)
المخرجات:
7 (00111)

خطوات الخوارزمية

المطلوب هو التبديل بين مجموعتين من البتات؛ لذا يمكن استخدام العامل XOR بنفس الطريقة التي يستخدم فيها هذا العامل للتبديل بين رقمين.

تتبع الخوارزمية الخطوات التالية:

  1. تحريك جميع البتات في المجموعة الأولى إلى أقصى اليمين
set1 = (x >> p1) &((1U << n) - 1)

يعطي التعبير ‎(1U << n) - 1 عددًا يحتوي على آخر n من البتات المعينة وتكون بقية البتات أصفارًا. يستخدم العامل & في هذا التعبير لتحويل بقية البتات إلى أصفار.

  1. تحريك جميع البتات في المجموعة الثانية إلى أقصى اليمين
set2 =  (x >> p2) & ((1U << n) - 1)
  1. استخدام العامل XOR مع مجموعتي البتات
xor = (set1 ^ set2)
  1. إرجاع البتات الناتجة من الخطوة السابقة إلى مواقعها الأصلية
xor = (xor << p1) | (xor << p2)
  1. استخدام العامل XOR مع مجموعة البتات الناتجة من الخطوة 4 والعدد الأصلي ليجري التبديل بين المجموعتين.
result = x ^ xor

تنفيذ الخوارزمية

تعرض الأمثلة التالية طريقة تنفيذ الخوارزمية في عدد من لغات البرمجة:

  • C++‎:
#include <bits/stdc++.h> 
using namespace std; 

int swapBits(unsigned int x, unsigned int p1, 
			unsigned int p2, unsigned int n) 
{ 
	/* تحريك جميع البتات في المجموعة الأولى إلى أقصى اليمين */
	unsigned int set1 = (x >> p1) & ((1U << n) - 1); 

	/* تحريك جميع البتات في المجموعة الثانية إلى أقصى اليمين */
	unsigned int set2 = (x >> p2) & ((1U << n) - 1); 

	/* استخدام العامل XOR مع مجموعتي البتات */
	unsigned int Xor = (set1 ^ set2); 

	/* إرجاع البتات الناتجة من الخطوة السابقة إلى مواقعها الأصلية */
	Xor = (Xor << p1) | (Xor << p2); 

	/* استخدام العامل `XOR` مع مجموعة البتات الناتجة من الخطوة 4 والعدد الأصلي ليجري التبديل بين المجموعتين */
	unsigned int result = x ^ Xor; 

	return result; 
} 

/* اختبار الدالة السابقة */
int main() 
{ 
	int res = swapBits(28, 0, 3, 2); 
	cout << "Result = " << res; 
	return 0; 
}
  • بايثون:
def swapBits(x,p1,p2,n): 

	# تحريك جميع البتات في المجموعة الأولى إلى أقصى اليمين 
	set1 = (x >> p1) & ((1<< n) - 1) 

	# تحريك جميع البتات في المجموعة الثانية إلى أقصى اليمين 
	set2 = (x >> p2) & ((1 << n) - 1) 

	# استخدام العامل XOR مع مجموعتي البتات
	xor = (set1 ^ set2) 

	# إرجاع البتات الناتجة من الخطوة السابقة إلى مواقعها الأصلية
	xor = (xor << p1) | (xor << p2) 

	# استخدام العامل `XOR` مع مجموعة البتات الناتجة من الخطوة 4 والعدد الأصلي ليجري التبديل بين المجموعتين
	result = x ^ xor 

	return result 
	
# اختبار الدالة السابقة

res =swapBits(28, 0, 3, 2) 
print("Result =",res)
  • جافا:
class GFG { 
	
	static int swapBits(int x, int p1, int p2, int n) 
	{ 
		// تحريك جميع البتات في المجموعة الأولى إلى أقصى اليمين
		int set1 = (x >> p1) & ((1 << n) - 1); 
	
		// تحريك جميع البتات في المجموعة الثانية إلى أقصى اليمين
		int set2 = (x >> p2) & ((1 << n) - 1); 
	
		// استخدام العامل XOR مع مجموعتي البتات
		int xor = (set1 ^ set2); 
	
		// إرجاع البتات الناتجة من الخطوة السابقة إلى مواقعها الأصلية
		xor = (xor << p1) | (xor << p2); 
	
		// استخدام العامل `XOR` مع مجموعة البتات الناتجة من الخطوة 4 والعدد الأصلي ليجري التبديل بين المجموعتين 
		int result = x ^ xor; 
	
		return result; 
	} 
	
	// اختبار التابع السابق
	public static void main(String[] args) 
	{ 
		int res = swapBits(28, 0, 3, 2); 
		System.out.println("Result = " + res); 
	} 
}

مصادر