Python โปรแกรมสำหรับสลับตัวเลขสองตัวโดยไม่ใช้ตัวแปรที่สาม

⚡ สรุปอย่างชาญฉลาด

แลกเปลี่ยนping ตัวเลขสองตัวที่ไม่มีตัวแปรที่สามจะสลับค่ากันโดยใช้การบวกและการลบทางคณิตศาสตร์tracการดำเนินการ XOR ระดับบิต หรือเทคนิคทางคณิตศาสตร์ระดับบิต Python นอกจากนี้ยังสามารถสลับโดยตรงด้วยการแกะทูเพิลได้อีกด้วย

  • 🔘 วิธีแบบดั้งเดิม: โดยปกติแล้ว การสลับค่าจะเก็บค่าหนึ่งค่าไว้ในตัวแปรชั่วคราว ซึ่งเทคนิคเหล่านี้หลีกเลี่ยงวิธีดังกล่าว
  • การสลับเลขคณิต: สลับค่าโดยให้ a = a + b จากนั้น b = a − b จากนั้น a = a − b
  • 🔀 การสลับ XOR: ใช้ตัวดำเนินการ XOR ระดับบิตสามครั้งเพื่อสลับจำนวนเต็มโดยไม่ให้เกิดการโอเวอร์โฟลว์
  • 🧮 การคำนวณแบบบิต: ใช้ตัวดำเนินการ AND, OR และ complement เพื่อสร้างการบวกและการลบtraction
  • 🐍 Python ทางลัด: การแยกทูเปิล a, b = b, a จะสลับค่าสองค่าใดๆ ในบรรทัดเดียว
  • 🤖 ปัญญาประดิษฐ์และข้อมูล: การสลับทูเพิลและการจัดเรียงองค์ประกอบอาร์เรย์ใหม่โดยใช้ดัชนี NumPy ในการเตรียมการเรียนรู้ของเครื่องจักร

สลับสอง Numbers โดยไม่ต้องใช้ตัวแปรที่สาม

หัวข้อด้านล่างนี้จะกล่าวถึงสี่วิธีในการสลับค่าโดยไม่ต้องใช้ตัวแปรชั่วคราว รวมถึงปัญหาการคำนวณเกินขีดจำกัด (arithmetic overflow)

ในภาษาโปรแกรม การสลับping หมายถึงการสลับค่าของตัวแปรสองตัว ตัวแปรนั้นอาจมีค่าเป็นตัวเลข สตริง รายการ หรืออาร์เรย์ อ็อบเจ็กต์ ฯลฯ โดยทั่วไปแล้ว การสลับค่าจะมีรูปแบบดังนี้ping คือการใช้ตัวแปรชั่วคราวเพื่อเก็บค่า ตัวอย่างเช่น

สลับสอง Numbers

ขั้นตอนทั่วไปของการแลกเปลี่ยนping ตัวเลขสองตัวคือ:

  • ประกาศตัวแปรชั่วคราว C
  • กำหนดค่าของ A ถึง C ซึ่งหมายถึง C = A ตอนนี้ C = 20
  • กำหนดค่าของ B ถึง A ดังนั้น A = 30
  • กำหนดค่าของ C ถึง B ดังนั้น B = 20 เนื่องจาก C มีค่า 20

นี่คือวิธีการสลับping การคำนวณนี้ทำได้โดยใช้ตัวแปรชั่วคราว และใช้ได้กับทั้งจำนวนเต็มและจำนวนทศนิยม

สลับโดยใช้สมการเลขคณิต

อย่างที่เราทราบกันดี การแลกเปลี่ยนping หมายถึงการสลับเปลี่ยนเนื้อหาของวัตถุ ฟิลด์ หรือตัวแปรสองตัว การสลับโดยใช้การดำเนินการทางคณิตศาสตร์ หมายถึงการสลับโดยใช้สมการทางคณิตศาสตร์ เช่น การบวกและการลบtraction

ถ้าเราได้รับตัวเลขสองตัวและถูกขอให้สลับตัวเลขโดยไม่ใช้ตัวแปรชั่วคราว เราสามารถสลับตัวเลขเหล่านั้นได้โดยใช้สมการทางคณิตศาสตร์สามสมการ

รหัสเทียมสำหรับการสลับping ตัวเลขโดยใช้การดำเนินการทางคณิตศาสตร์:

A = A + B
B = A - B
A = A - B

สมมติว่าเรามีตัวเลขสองตัว คือ A = 20 และ B = 30

เงื่อนไขที่ 1: ก = ก+ข

ดังนั้น ค่าปัจจุบันของ A คือ 20 + 30 = 50

เงื่อนไขที่ 2: บี = เอบี

ตอนนี้ B = 50-30 = 20
เราจะเห็นได้ว่าเราได้ค่าของ A ใน B แล้ว

เงื่อนไขที่ 3: ก = เอบี

สุดท้าย A = 50-20 = 30
A มีค่าเริ่มต้นเป็น B

แล้วเราก็สลับตัวเลขกัน

นี่คือโปรแกรมสำหรับสลับตัวเลขสองตัวในภาษาซี/C++:

#include<stdio.h>
int main()
{
	int a, b;
	printf("Enter value of A: ");
	scanf("%d", & a);
	printf("Enter value of B: ");
	scanf("%d", & b);
	printf("A = %d, B = %d", a, b);
	a = a + b;
	b = a - b;
	a = a - b;
	printf("\nNow, A = %d, B = %d", a, b);
}

Output:

Enter value of A: 20
Enter value of B: 30
A = 20 , B = 30
Now, A = 30 , B = 20

โปรแกรมใน Python:

a = int(input("Enter value of A: "))
b = int(input("Enter value of B: "))
print("A = {} and B = {}".format(a, b))
a = a + b
b = a - b
a = a - b
print("Now, A = {} and B = {}".format(a, b))

Output:

Enter value of A: 20
Enter value of B: 30
A = 20 , B = 30
Now, A = 30 , B = 20

ตอนนี้ใน Pythonเราไม่จำเป็นต้องทำการคำนวณทางคณิตศาสตร์เลยด้วยซ้ำ เราสามารถใช้:

ก,ข = ข,ก

ต่อไปนี้เป็นตัวอย่างที่ a=20, b=30;

สลับโดยใช้สมการเลขคณิต

สลับโดยใช้ Bitwise XOR OperaTor

วิธีนี้เรียกอีกอย่างว่าการสลับแบบ XOR XOR ย่อมาจาก Exclusive OR ในการดำเนินการแบบบิตไวส์นี้ เราใช้บิตสองบิตเป็นอินพุต เพื่อให้ได้เอาต์พุตหนึ่งเดียวจาก XOR อินพุตเพียงหนึ่งเดียวเท่านั้นที่ต้องเป็น 1 มิฉะนั้นเอาต์พุตจะเป็น 0 ตารางต่อไปนี้แสดงเอาต์พุตสำหรับทุกชุดค่าผสมของอินพุต A และ B

เราจำเป็นต้องเข้าใจวิธีการทำงานของโอเปอเรชั่น XOR เพื่อสลับตัวเลขสองตัวโดยใช้การดำเนินการแบบบิต นี่คือตารางแสดงค่า XOR โดยที่ A และ B คือค่าอินพุต

A B เอ เอ็กซ์ออร์ บี
0 0 0
0 1 1
1 0 1
1 1 0

ถ้าค่าอินพุตสองค่าเหมือนกัน การดำเนินการ XOR จะให้ผลลัพธ์เป็น 0 มิฉะนั้นจะให้ผลลัพธ์เป็น 1 ในตัวอย่างนี้ เราจะใช้การดำเนินการ XOR 3 ตัว ในภาษาโปรแกรมส่วนใหญ่ การดำเนินการ XOR จะใช้สัญลักษณ์ “^”

สมมติให้ A=4 (ในระบบเลขฐานสอง = 0100) และ B=7 (ในระบบเลขฐานสอง = 0111)

เงื่อนไขที่ 1: ก = ก ^ บี

A 0 1 0 0
B 0 1 1 1
เอ ^ บี 0 0 1 1

ตอนนี้ A = 0011 (ในรูปแบบไบนารี)

เงื่อนไขที่ 2: บี = เอ^บี

A 0 0 1 1
B 0 1 1 1
เอ ^ บี 0 1 0 0

ดังนั้น B = 0100 ซึ่งเป็นค่าไบนารีเริ่มต้นของ A

เงื่อนไขที่ 3: ก = ก^ข

A 0 0 1 1
B 0 1 0 0
เอ ^ บี 0 1 1 1

สุดท้าย A = 0111 ซึ่งเป็นค่าไบนารี่ที่เทียบเท่ากับ B

โปรแกรมในภาษา C/C++:

#include<stdio.h>
int main()
{
	int a, b;
	printf("Enter value of A: ");
	scanf("%d", & a);
	printf("Enter value of B: ");
	scanf("%d", & b);
	printf("A = %d, B = %d", a, b);
	a = a ^ b;
	b = a ^ b;
	a = a ^ b;
	printf("\nNow, A = %d, B = %d", a, b);
}

Output:

Enter value of A:4
Enter value of B:7
A=4, B=7
Now, A=7, B=4.

โปรแกรมใน Python:

a = int(input("Enter value of A: "))
b = int(input("Enter value of B: "))
print("A = {} and B = {}".format(a, b))
a = a ^ b
b = a ^ b
a = a ^ b
print("Now, A = {} and B = {}".format(a, b))

Output:

Enter the value of A:10
Enter the value of B:15
A=10 and B=15
Now, A=15,B=10.

แลกเปลี่ยน Numbers โดยใช้ Bitwise-Arithmetic

วิธีนี้เหมือนกับวิธีทางเลขคณิต แต่เราจะใช้การดำเนินการระดับบิต เช่น AND, OR และส่วนเติมเต็ม เพื่อทำการบวกและลบtracก่อนที่จะไปถึงขั้นตอนต่างๆ เรามาดูความหมายของคำว่า “ส่วนเติมเต็ม” กันอย่างรวดเร็วก่อน

1's complement หมายถึงการเปลี่ยนเลข 0 ทั้งหมดให้เป็น 1 และเลข 1 ทั้งหมดให้เป็น 0 ลองมาดูตัวอย่างกัน

  • สมมติว่าเรามีเลข 23 ซึ่งเป็นเลขทศนิยม
  • การแปลงเป็นเลขฐานสองจะได้ 10111 มีเพียง 5 บิต แต่คอมพิวเตอร์เก็บตัวเลขใน 8, 16, 32, 64 … บิต ดังนั้น เรามาเติมเลขศูนย์ไว้ข้างหน้าเลขฐานสองกันเถอะ มันจะไม่เปลี่ยนแปลงค่าเดิมของตัวเลข ดังนั้นมันจะกลายเป็น 10111 00010111.
  • อย่างที่เราทราบกันดี 1's complement หมายถึงการเปลี่ยน 0 ทั้งหมดให้เป็น 1 และ 1 ทั้งหมดให้เป็น 0 ดังนั้นการทำ 1's complement กับ... 00010111 จะช่วยให้ 11101000.

ค่าคอมพลีเมนต์ 1 นี้แสดงด้วยสัญลักษณ์ “~” ในภาษาโปรแกรมส่วนใหญ่ การใส่สัญลักษณ์นี้ไว้หน้าค่าจำนวนเต็มหรือค่าทศนิยมใดๆ จะให้ค่าคอมพลีเมนต์ 1 นั้น

ส่วนเสริมของ 2 หมายถึงการบวกเลขฐานสอง “1” เข้าไปในส่วนเสริมของ 1 หากเราทำส่วนเสริมของ 2 กับตัวเลขด้านบน:

  • ไบนารี = 00010111
  • ส่วนเติมเต็ม 1 = 11101000
  • ส่วนเติมเต็มของ 2:

11101000

+ 1

11101001

ส่วนเสริมของ 2 คือ 11101001 นี่คือไบนารี่ของ -23
โดยสรุป สำหรับการแสดงส่วนเสริม 2 ของตัวเลข A จะมีลักษณะดังนี้:

ส่วนเสริมของ 2 ของ A = (~A) + 1

ต่อไปนี้เราจะสมมติว่า A=8 (เลขฐานสอง 00001000) และ B=10 (00001010)

เงื่อนไขที่ 1: ก = (ก & ข) + (ก | ข)

มันเทียบเท่ากับ A = A + B

เอ และ บี = 00001000 & 00001010 = 00001000

ก | บี = 00001000 | 00001010 = 00001010

ตอนนี้ 00001000 + 00001010 = 00010010 (ทศนิยม 18)

ดังนั้น A = 18

เงื่อนไขที่ 2: ข = ก + (~ข) + 1

มันเทียบเท่ากับ B = AB

ในที่นี้ B = A – B

จากที่กล่าวมาข้างต้น หากเราจำเป็นต้องทำขั้นตอนย่อยtracในกรณีดังกล่าว เราจะทำการหาค่า 2's complement ให้กับจำนวนลบ แล้วจึงบวกเข้ากับจำนวนนั้น

ดังนั้น -B = ~B + 1

ตอนนี้ B = 00010010 + (11110101) + 1 = 00001000

ค่าของ B เทียบเท่ากับทศนิยม 8 ซึ่งเป็นค่าเริ่มต้น

เงื่อนไขที่ 3: ก = ก + (~B) + 1

มันเทียบเท่ากับ A = AB

ตอนนี้ A = 00010010 + 11110111 + 1

A = 00001010 (เทียบเท่ากับทศนิยม 10)

ในที่สุด A ก็ได้ค่าเท่ากับ B ดังนั้น การสลับจึงเกิดขึ้นping เป็นที่เรียบร้อยแล้ว.

โปรแกรมในภาษา C/C++:

#include<stdio.h>
int main()
{
	int a, b;
	printf("Enter value of A: ");
	scanf("%d", & a);
	printf("Enter value of B: ");
	scanf("%d", & b);
	printf("A = %d, B = %d", a, b);
	a = (a & b) + (a | b);
	b = a + ~b + 1;
	a = a + ~b + 1;
	printf("\nNow, A = %d, B = %d", a, b);
}

Output:

Enter the value of A: 8
Enter the value of B:10
A=8, B=10
Now, A=10, B=8

โปรแกรมใน Python:

a = int(input("Enter value of A: "))
b = int(input("Enter value of B: "))
print("A = {} and B = {}".format(a, b))
a = (a & b) + (a | b)
b = a + ~b + 1
a = a + ~b + 1
print("Now, A = {} and B = {}".format(a, b))

Output:

Enter the value of A: 25
Enter the value of B: 25
A = 25 and B = 25
Now, A = 25 and B = 25

เลขคณิตล้นคืออะไร?

คำว่า "โอเวอร์โฟลว์" หมายถึงการเกินขีดจำกัด โอเวอร์โฟลว์ทางคณิตศาสตร์หมายความว่าผลลัพธ์ของการดำเนินการทางคณิตศาสตร์ใดๆ เกินขอบเขตหรือขีดจำกัดของการแสดงตัวเลขของสถาปัตยกรรมคอมพิวเตอร์ ตัวอย่างเช่น หากหารตัวเลขด้วยศูนย์ ผลลัพธ์จะเป็นอนันต์ และระบบตัวเลขของคอมพิวเตอร์ไม่สามารถเก็บค่านี้ไว้ใน 32 หรือ 64 บิตได้

การแทนจำนวนเต็ม

การแสดงจำนวนเต็มในระบบ 32 บิต

ผลที่ตามมาของการโอเวอร์โฟลว์ทางคณิตศาสตร์อาจเป็น:

  • การบวกจำนวนบวกสองจำนวนจะกลายเป็นจำนวนลบ เนื่องจากบิตเครื่องหมายอาจเป็น 1 ซึ่งหมายถึงจำนวนลบ
  • การบวกจำนวนลบสองจำนวนจะได้ผลลัพธ์เป็นบวก เนื่องจากบิตเครื่องหมายอาจเป็น 0 ซึ่งหมายถึงจำนวนบวก

คำถามที่พบบ่อย

การสลับ XORping เป็นตัวเลือกที่ได้รับความนิยมในการสัมภาษณ์: ไม่ต้องใช้หน่วยความจำเพิ่มเติม ไม่มีปัญหาข้อมูลล้น การคำนวณทางคณิตศาสตร์เป็นตัวเลือกสำรองที่ดี และ Python โดยปกติแล้วนักพัฒนาจะเขียนแค่ว่า a, b = b, a

ไม่ การดำเนินการ XOR แบบบิตต่อบิตใช้ได้เฉพาะกับรูปแบบบิตจำนวนเต็มเท่านั้น ไม่ใช่จำนวนทศนิยม จำนวนสองเท่า หรือตัวชี้ สำหรับจำนวนทศนิยม ให้ใช้การแยกทูเพิลหรือการสลับทางคณิตศาสตร์แทน

ถ้าตัวแปรทั้งสองใช้พื้นที่หน่วยความจำร่วมกัน ให้ใช้การดำเนินการ XOR เพื่อสลับตัวแปรping ตั้งค่าเป็น 0 เพิ่มการตรวจสอบเงื่อนไข if ทุกครั้งที่สามารถกำหนดชื่อแทนได้

ใช่: a = a * b, b = a / b, a = a / b แต่จะล้มเหลวเมื่อค่าใดค่าหนึ่งเป็น 0 และจะสูญเสียความแม่นยำของเลขทศนิยม

ทำได้เฉพาะการแยกทูเพิลเท่านั้น การเขียน a, b = b, a จะสลับสตริง รายการ หรือออบเจ็กต์ ส่วนการคำนวณทางคณิตศาสตร์และเทคนิค XOR นั้นใช้ได้เฉพาะกับจำนวนเต็มเท่านั้น

แทบจะไม่มีผลเลย คอมไพเลอร์สมัยใหม่ได้ทำการปรับแต่งการสลับตัวแปรชั่วคราวอยู่แล้ว ดังนั้นเทคนิคนี้จึงแทบไม่ช่วยเพิ่มความเร็วเลย Readable โค้ดมีความสำคัญมากกว่าการบันทึกค่าตัวแปรเพียงค่าเดียว

ใช่แล้ว โค้ดแมชชีนเลิร์นนิงจะสลับค่ากับ Python การแยกทูเพิล และ นำพาย การกำหนดดัชนีเช่น arr[[i, j]] = arr[[j, i]] จะสลับแถวของอาร์เรย์ในตำแหน่งเดิม

ใช่แล้ว GitHub Copilot และผู้ช่วย AI ที่คล้ายกัน สามารถทำการคำนวณ XOR, คำนวณเลขคณิต และสลับค่าในทูเพิลได้จากข้อความแจ้ง Revตรวจสอบแต่ละรายการเพื่อหาข้อผิดพลาดเกี่ยวกับการล้นค่าและการใช้ชื่อแทนกัน

สรุปโพสต์นี้ด้วย: