Triển Khai Thuật Toán Tìm Số Armstrong Trong Visual Basic .NET

Số Armstrong, còn được biết đến với tên gọi số thủy tiên hoặc số Narcissistic, là một số nguyên dương có n chữ số sao cho tổng lũy thừa bậc n của từng chữ số bằng chính số đó. Ví dụ, với số có 3 chữ số, tổng lập phương của các chữ số phải bằng giá trị của số ấy. Bài viết này sẽ hướng dẫn cách xây dựng chương trình trên nền tảng Visual Basic .NET để xác định các số thỏa mãn điều kiện này.

Nguyên lý hoạt động của thuật toán

Để tìm ra các số Armstrong, phương pháp phổ biến nhất là duyệt toàn bộ (brute-force) trong một khoảng xác định. Với một số có n chữ số, khoảng giá trị sẽ bắt đầu từ $10^{n-1}$ và kết thúc tại $10^n - 1$. Với mỗi giá trị trong khoảng này, chương trình sẽ tách từng chữ số, tính lũy thừa bậc n và cộng dồn lại. Nếu tổng thu được trùng với số ban đầu, đó là một số Armstrong.

Ngôn ngữ Visual Basic .NET cung cấp các toán tử số học và cấu trúc vòng lặp linh hoạt, giúp việc triển khai logic này trở nên đơn giản và dễ đọc. Chúng ta có thể sử dụng phép chia lấy dư (Mod) để lấy chữ số cuối cùng và phép chia nguyên (\) để loại bỏ chữ số đó khỏi số gốc.

Triển khai cố định số chữ số

Trong ví dụ đầu tiên, chúng ta sẽ thiết lập sẵn số chữ số là 3. Chương trình sẽ quét toàn bộ các số từ 100 đến 999. Để mã nguồn gọn gàng hơn, logic kiểm tra sẽ được tách riêng vào một hàm phụ trợ.

Imports System

Module KiemTraSo
    Sub Main()
        Dim bac As Integer = 3
        Dim danhSachKetQua As New List(Of Integer)()
        Dim dau As Integer = CInt(Math.Pow(10, bac - 1))
        Dim cuoi As Integer = CInt(Math.Pow(10, bac)) - 1

        For giaTri As Integer = dau To cuoi
            If IsArmstrong(giaTri, bac) Then
                danhSachKetQua.Add(giaTri)
            End If
        Next

        Console.WriteLine("Danh sach so Armstrong (3 chu so):")
        For Each so In danhSachKetQua
            Console.WriteLine(so)
        Next
    End Sub

    Function IsArmstrong(so As Integer, mu As Integer) As Boolean
        Dim tong As Integer = 0
        Dim temp As Integer = so
        
        Do While temp > 0
            Dim chuso As Integer = temp Mod 10
            tong += CInt(Math.Pow(chuso, mu))
            temp \= 10
        Loop

        Return tong = so
    End Function
End Module

Đoạn mã trên khởi tạo khoảng chạy dựa trên biến `bac`. Hàm `IsArmstrong` chịu trách nhiệm tính toán tổng lũy thừa. Việc sử dụng `Math.Pow` thay cho toán tử `^` trực tiếp giúp tăng tính tường minh khi làm việc với kiểu dữ liệu số thực trước khi ép kiểu về nguyên.

Mở rộng cho số chữ số bất kỳ

Để chương trình linh hoạt hơn, chúng ta có thể cho phép người dùng nhập vào số lượng chữ số mong muốn qua giao diện console. Logic xử lý vẫn giữ nguyên, chỉ thay đổi cách khởi tạo giá trị n và thêm phần đọc dữ liệu đầu vào.

Imports System

Module KiemTraSo
    Sub Main()
        Console.Write("Nhap so chu so (n): ")
        Dim input As String = Console.ReadLine()
        Dim bac As Integer = 0

        If Integer.TryParse(input, bac) AndAlso bac > 0 Then
            Dim ketQua As New List(Of Integer)()
            Dim minVal As Integer = CInt(Math.Pow(10, bac - 1))
            Dim maxVal As Integer = CInt(Math.Pow(10, bac)) - 1

            For i As Integer = minVal To maxVal
                If TinhTongLuyThua(i, bac) = i Then
                    ketQua.Add(i)
                End If
            Next

            Console.WriteLine("Ket qua tim duoc:")
            For Each val In ketQua
                Console.WriteLine(val)
            Next
        Else
            Console.WriteLine("Gia tri nhap khong hop le.")
        End If

        Console.ReadLine()
    End Sub

    Function TinhTongLuyThua(soGoc As Integer, mu As Integer) As Integer
        Dim tongLuyThua As Integer = 0
        Dim bienTam As Integer = soGoc

        While bienTam >= 1
            Dim chuSoHang As Integer = bienTam Mod 10
            tongLuyThua += CInt(Math.Pow(chuSoHang, mu))
            bienTam \= 10
        End While

        Return tongLuyThua
    End Function
End Module

Trong phiên bản này, hàm `Integer.TryParse` được sử dụng để đảm bảo dữ liệu đầu vào hợp lệ trước khi thực thi vòng lặp. Biến `minVal` và `maxVal` xác định ranh giới duyệt dựa trên lũy thừa của 10. Hàm `TinhTongLuyThua` thực hiện việc tách số và tính toán tổng, trả về giá trị để so sánh với số gốc ngay trong vòng lặp chính.

Thẻ: visual-basic.net armstrong-numbers console-application algorithm-implementation numeric-analysis

Đăng vào ngày 19 tháng 6 lúc 10:21