ตัวเลขอาร์มสตรองในโปรแกรม JAVA โดยใช้ For Loop

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

เลขอาร์มสตรองเท่ากับผลรวมของตัวเลขแต่ละหลักยกกำลังด้วยจำนวนหลัก และสอง Java โปรแกรมด้านล่างจะตรวจสอบค่าเพียงค่าเดียวและแสดงรายการตัวเลขอาร์มสตรองทั้งหมดที่ต่ำกว่าหนึ่งพัน

  • 🔘 ความหมาย: สำหรับจำนวนที่มี n หลัก แต่ละหลักจะถูกยกกำลัง n แล้วนำผลลัพธ์มาบวกกัน
  • ☑️ ตัวอย่างการทำงาน: 370 เข้าเกณฑ์เพราะ 3³ บวก 7³ บวก 0³ ได้ผลลัพธ์เท่ากับ 370 พอดี
  • Digiทีเอ็กซ์tracชั่น: ตัวดำเนินการโมดูลัสจะตัดตัวเลขหลักสุดท้ายออก และการหารจำนวนเต็มจะทำให้ตัวเลขสั้นลงในแต่ละรอบ
  • 🧪 สองโปรแกรม: โค้ดส่วนหนึ่งทดสอบค่าที่กำหนดไว้ตายตัวคือ 153 ส่วนอีกส่วนหนึ่งวนลูปผ่านทุกตัวเลขตั้งแต่ 0 ถึง 999
  • 🛠️ ขีดจำกัดที่ทราบ: การยกกำลังสามของแต่ละหลักใช้ได้เฉพาะกับตัวเลขสามหลักเท่านั้น ดังนั้นสำหรับช่วงตัวเลขที่กว้างกว่านั้นจึงต้องใช้เลขยกกำลัง n
  • 📊 ซับซ้อน: ทั้งสองโปรแกรมทำงานโดยใช้เวลา O(d) ต่อตัวเลข และใช้หน่วยความจำเพิ่มเติม O(1)

หมายเลขอาร์มสตรองใน Java โปรแกรมที่ใช้ลูป for

หมายเลขอาร์มสตรองคืออะไร?

ในจำนวนอาร์มสตรอง ผลรวมของกำลังหลักแต่ละหลักจะเท่ากับจำนวนนั้นเอง

กล่าวอีกนัยหนึ่งสมการต่อไปนี้จะถือเป็นจริง

xy..z = xn + yn+.....+ zn

n คือจำนวนหลักในจำนวน

ตัวอย่างเช่น นี่คือเลขอาร์มสตรอง 3 หลัก

370 = 33 + 73 + 03
 = 27 + 343 + 0
 = 370

ตัวอย่างของอาร์มสตรอง Numbers

0, 1, 4, 5, 9, 153, 371, 407, 8208, etc.

ค่าตัวเลขหลักเดียวทุกค่าตั้งแต่ 0 ถึง 9 สอดคล้องกับกฎนี้ได้อย่างง่ายดาย เพราะตัวเลขหลักเดียวที่ยกกำลังหนึ่งจะได้ผลลัพธ์เป็นตัวมันเอง เซตของตัวเลขอาร์มสตรองสามหลักที่สมบูรณ์คือ 153, 370, 371 และ 407 ในขณะที่ 1634, 8208 และ 9474 เป็นตัวเลขสี่หลัก นักคณิตศาสตร์เรียกค่าเหล่านี้ว่าตัวเลขหลงตัวเอง (narcissistic numbers) เนื่องจากแต่ละจำนวนสามารถสร้างตัวเองขึ้นมาใหม่ได้จากตัวเลขหลักเดียวของมันเอง

มาเขียนสิ่งนี้ในโปรแกรม:

วิธีการทำงานของอัลกอริธึมเลขอาร์มสตรอง

ก่อนที่จะอ่านโค้ด การดูวิธีการคำนวณที่ทั้งสองโปรแกรมใช้ซ้ำจะช่วยได้ การตรวจสอบนั้นต้องการเพียงสามขั้นตอนเท่านั้น คือ ตัดหลักสุดท้ายออก ยกกำลังด้วยตัวเลขที่ต้องการ และลดจำนวนลงหนึ่งหลัก

  1. คัดลอกข้อมูลป้อนเข้าลงในไฟล์ใช้งาน ตัวแปร ดังนั้นค่าเดิมจึงยังคงอยู่สำหรับการเปรียบเทียบขั้นสุดท้าย
  2. นำตัวเลขหลักสุดท้ายมาหารด้วยตัวดำเนินการโมดูลัส digit = tempNumber % 10.
  3. ยกกำลังตัวเลขนั้นด้วยจำนวนหลัก แล้วบวกเข้ากับผลรวมสะสม
  4. ตัดตัวเลขหลักสุดท้ายด้วยการหารจำนวนเต็ม tempNumber /= 10.
  5. ทำซ้ำจนกว่าตัวแปรทำงานจะถึง 0 จากนั้นเปรียบเทียบผลรวมที่สะสมกับตัวเลขเริ่มต้น

การดำเนินการตามขั้นตอนเหล่านั้นซ้ำ 153 ครั้ง จะได้ผลลัพธ์ดังนี้ tracดูด้านล่าง ค่าทุกค่าในตารางจะถูกพิมพ์โดยโปรแกรมแรก ดังนั้นผลลัพธ์จึงสามารถนำมาเปรียบเทียบทีละบรรทัดขณะเรียนรู้ลูปได้

ส่ง หมายเลขชั่วคราว เลข ผลรวมลูกบาศก์ตัวเลข
1 153 3 27
2 15 5 152
3 1 1 153
ทางออก 0 - 153 เท่ากับ 153 ดังนั้น 153 จึงเป็นเลขอาร์มสตรอง

ข้อจำกัดที่สำคัญอย่างหนึ่ง ทั้งสองโปรแกรมคูณตัวเลขนั้นด้วยตัวเองสามครั้ง ซึ่งเป็นเลขยกกำลังที่ถูกต้องเฉพาะเมื่ออินพุตมีตัวเลขสามหลักพอดีเท่านั้น กฎทั่วไปคือการยกกำลังแต่ละหลักด้วย n โดยที่ n คือจำนวนหลัก ดังนั้นค่าสี่หลักเช่น 8208 จึงต้องใช้เลขยกกำลังสี่ และโค้ดที่ใช้เลขยกกำลังสามจะมองข้ามไป การนับจำนวนหลักก่อนแล้วยกกำลังแต่ละหลักด้วยเลขยกกำลังนั้นเองที่ทำให้รูทีนนี้กลายเป็นการทดสอบทั่วไป

เมื่อเข้าใจหลักการคำนวณแล้ว โปรแกรมแรกจะนำหลักการคำนวณไปใช้กับค่าคงที่ค่าเดียว

Java โปรแกรมเช็คว่าเลขนั้นเป็นเลขอาร์มสตรองหรือไม่

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

//ChecktempNumber is Armstrong or not using while loop
package com.guru99;
 
public class ArmstrongNumber {
	public static void main(String[] args) {
		 int inputArmstrongNumber = 153; //Input number to check armstrong  
		 int tempNumber, digit, digitCubeSum = 0;
	       tempNumber = inputArmstrongNumber;
	        while (tempNumber != 0)
	        {
	        	/* On each iteration, remainder is powered by thetempNumber of digits n
	        	 */
	            System.out.println("Current Number is "+tempNumber);
	            digit =tempNumber % 10;
				System.out.println("Current Digit is "+digit);
	            //sum of cubes of each digits is equal to thetempNumber itself
	            digitCubeSum = digitCubeSum + digit*digit*digit;
				System.out.println("Current digitCubeSum is "+digitCubeSum);
	            tempNumber /= 10;
	        }
	        //check giventempNumber and digitCubeSum is equal to or not 
	        if(digitCubeSum == inputArmstrongNumber)
	            System.out.println(inputArmstrongNumber + " is an Armstrong Number");
	        else
	            System.out.println(inputArmstrongNumber + " is not an Armstrong Number");
	}
}

คอมไพล์และรันคลาสจากไดเร็กทอรีหลักของโปรเจ็กต์ เนื่องจากไฟล์ดังกล่าวประกาศไว้ package com.guru99มันต้องวางอยู่ในที่ที่เข้ากัน com/guru99 โฟลเดอร์ หรือรันไทม์รายงานข้อผิดพลาดว่าไม่พบคลาส การเปลี่ยนค่าบน inputArmstrongNumber เพียงแค่บรรทัดเดียวก็เพียงพอที่จะทดสอบผู้สมัครคนอื่นได้แล้ว

เอาท์พุต

Current Number is 153
Current Digit is 3
Current digitCubeSum is 27
Current Number is 15
Current Digit is 5
Current digitCubeSum is 152
Current Number is 1
Current Digit is 1
Current digitCubeSum is 153
153 is an Armstrong Number

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

Java โปรแกรมพิมพ์ตัวเลขอาร์มสตรองตั้งแต่ 0 ถึง 999

เวอร์ชั่นที่สองยังคงมีโครงสร้างภายในเหมือนเดิมทุกประการ while วนซ้ำและเพิ่ม for ลูปที่เดินตามช่วง โปรดทราบว่า digitCubeSum ค่านี้จะถูกรีเซ็ตเป็น 0 ทุกครั้งที่เริ่มต้นการทำงาน ซึ่งเป็นรายละเอียดที่ผู้เริ่มต้นส่วนใหญ่มักลืมไป

//ChecktempNumber is Armstrong or not using while loop
package com.guru99;
public class ArmstrongNumber {
    public static void main(String[] args) {
        int tempNumber, digit, digitCubeSum;
        for (int inputArmstrongNumber = 0; inputArmstrongNumber < 1000; inputArmstrongNumber++) {
            tempNumber = inputArmstrongNumber;
            digitCubeSum = 0;
            while (tempNumber != 0) {
                /* On each iteration, remainder is powered by thetempNumber of digits n
                 */
                digit = tempNumber % 10;
                //sum of cubes of each digits is equal to thetempNumber itself
                digitCubeSum = digitCubeSum + digit * digit * digit;
                tempNumber /= 10;
            }
            //check giventempNumber and digitCubeSum is equal to or not 
            if (digitCubeSum == inputArmstrongNumber)
                System.out.println(inputArmstrongNumber + " is an Armstrong Number");
        }
    }
}

เอาท์พุต

0 is an Armstrong Number
1 is an Armstrong Number
153 is an Armstrong Number
370 is an Armstrong Number
371 is an Armstrong Number
407 is an Armstrong Number

รายการจะหยุดที่ 1 แทนที่จะต่อเนื่องไปถึง 9 เพราะกำลังสามของตัวเลขหลักเดียวจะตรงกับตัวเลขนั้นเองเฉพาะในกรณีของ 0 และ 1 เท่านั้น การยกกำลังตัวเลขแต่ละหลักด้วยจำนวนตัวเลขแทนจะให้ค่าตัวเลขหลักเดียวทั้งสิบค่า ซึ่งเป็นการสรุปแบบเดียวกันกับที่อธิบายไว้ก่อนหน้านี้

ทั้งสองรายการมีความยาวสั้นพอที่จะใช้เป็นเกณฑ์มาตรฐานได้ ดังนั้นจึงควรระบุต้นทุนของวิธีการนี้อย่างชัดเจน

ความซับซ้อนของเวลาและพื้นที่ของโครงการเลขอาร์มสตรอง

ลูปภายในจะหารตัวแปรทำงานด้วย 10 ในทุกรอบการทำงาน ดังนั้นจึงทำงานหนึ่งครั้งต่อหลัก แทนที่จะทำงานหนึ่งครั้งต่อหน่วยของตัวเลข วิธีนี้ทำให้การตรวจสอบค่าเดียวมีต้นทุนต่ำมาก และยังคงมีต้นทุนต่ำแม้ว่าข้อมูลป้อนเข้าจะเพิ่มขึ้นก็ตาม

โครงการ ความซับซ้อนของเวลา ความซับซ้อนของพื้นที่
เลือกหมายเลขใดหมายเลขหนึ่ง O(d) โดยที่ d คือจำนวนหลัก O (1)
สแกนช่วงตัวเลข N O(N × d) O (1)

เนื่องจาก d เท่ากับ log10(ตัวเลข) ปัดขึ้น การตรวจสอบครั้งเดียวจะมีผลเหมือนลอการิทึมในค่าที่กำลังทดสอบ เพียงสาม int ไม่มีการจัดสรรตัวแปรใดๆ และไม่มีการสร้างอาร์เรย์หรือคอลเลกชันใดๆ ซึ่งเป็นเหตุผลว่าทำไมต้นทุนพื้นที่จึงคงที่ ไม่ว่าช่วงจะใหญ่แค่ไหนก็ตาม

จากข้อนี้มีข้อสังเกตเชิงปฏิบัติสองประการ ประการแรก การสแกนช่วงค่าส่วนใหญ่ขึ้นอยู่กับค่า N ดังนั้นการพิมพ์ตัวเลข Armstrong จนถึงหนึ่งล้านจึงมีค่าใช้จ่ายมากกว่าการพิมพ์จนถึงหนึ่งพันเท่าโดยประมาณ ประการที่สอง int ค่าเกิน 2,147,483,647 ทำให้การค้นหาในช่วงขนาดใหญ่มากต้องใช้ค่าเกินขีดจำกัด long สำหรับทั้งผู้สมัครและผลรวมสะสม ตัวเลขเดียวกัน-extracรูปแบบ tion ปรากฏในแบบฝึกหัดสำหรับผู้เริ่มต้นหลายแบบ รวมถึง การตรวจสอบจำนวนเฉพาะที่ ชุดฟีโบนักชี โปรแกรมและการฝึกซ้อมแบบต่างๆ เช่น เรียงฟอง และ การเรียงลำดับการแทรก.

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

ใช่แล้ว การยกกำลังสามของแต่ละหลักจะได้ 27 บวก 343 บวก 1 ซึ่งรวมกันได้ 371 ดังนั้นค่าจึงซ้ำกัน โปรแกรมช่วงข้างต้นพิมพ์ค่านี้ควบคู่ไปกับ 153, 370 และ 407

ชื่อนี้สะท้อนถึงคุณสมบัติของมันเอง: ตัวเลขนั้นสร้างขึ้นจากตัวเลขหลักเดียวของมันเองทั้งหมด ดังนั้นจึงดูเหมือนว่ามันชื่นชมภาพสะท้อนของตัวเอง ทั้งสองคำนี้อธิบายกฎเดียวกัน และผลรวมกำลังของตัวเลขหลักเดียวบางครั้งเรียกว่าตัวแปรคงที่ดิจิทัลแบบสมบูรณ์ (pluperfect digital invariant)

มีอยู่สามค่า ได้แก่ 1634, 8208 และ 9474 แต่ละหลักถูกยกกำลังสี่เพราะค่ามีสี่หลัก รหัสแบบลูกบาศก์ไม่สามารถตรวจจับค่าเหล่านี้ได้ ดังนั้นเลขชี้กำลังจึงต้องสอดคล้องกับจำนวนหลัก

จำนวนสมบูรณ์คือจำนวนที่เท่ากับผลรวมของตัวหารแท้ของมัน ดังนั้น 6 จึงเข้าเกณฑ์เพราะ 1 บวก 2 บวก 3 ส่วนจำนวนอาร์มสตรองคือจำนวนที่เท่ากับผลรวมของเลขชี้กำลังของตัวเลขแต่ละหลัก นิยามทั้งสองนี้ไม่มีความเกี่ยวข้องทางคณิตศาสตร์และแทบจะไม่ทับซ้อนกันเลย

เมธอด `Math.pow()` ส่งคืนค่า `double` ดังนั้นจึงจำเป็นต้องแปลงกลับเป็น `int` และอาจเกิดข้อผิดพลาดจากการปัดเศษได้ สำหรับลูกบาศก์ที่มีเลขชี้กำลังคงที่ วิธี `digit*digit*digit` จะเร็วกว่าและแม่นยำกว่า เมธอด `Math.pow()` จะมีประโยชน์ก็ต่อเมื่อเลขชี้กำลังเปลี่ยนแปลงไปตามจำนวนหลักเท่านั้น

ใช่แล้ว เมธอดช่วยสามารถรับค่าที่ใช้งานอยู่ เพิ่มเลขหลักสุดท้ายที่ยกกำลังแล้วลงในตัวสะสม และเรียกตัวเองซ้ำด้วยตัวเลขที่หารด้วย 10 ถึงแม้ว่าเวอร์ชันแบบวนลูปจะหลีกเลี่ยงเฟรมสแต็กเพิ่มเติมได้ แต่ก็อ่านง่ายดี

ผู้ช่วยสมัยใหม่สามารถสร้างทางเลี่ยงได้ trace. อธิบายลูปอีกครั้งด้วยภาษาที่เข้าใจง่าย และยกตัวอย่างกรณีพิเศษ เช่น 0 หรือค่าอินพุตติดลบ ตรวจสอบ trace เมื่อเทียบกับผลลัพธ์ที่แสดงบนคอนโซลจริง เนื่องจากคำแนะนำที่สร้างขึ้นอาจข้ามขั้นตอนไปบ้างในบางครั้ง

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

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