Sao anh bạn không bôi luôn dòng
Anh có hiểu thế nào là khái quát không ạ? Hay là anh bạn có vẻ nhiệt tình đi vô những cái quá cụ thể, tiểu tiết?
Nếu thuật giải được mô tả chi tiết, cụ thể tới mức cần như anh nói thì thật tình có những thuật giải không tài nào mô tả được đặc biệt là nếu phải dùng lưu đồ vì quá nhiều nhánh, quá nhiều công việc, trường hợp nhỏ nhặt phải liệt kê ra.
Đừng đồng hóa giữa viết code và thuật giải. Thuật giải chỉ cho người ta cái nhìn khái quát của tiến trình giải quyết chứ nó không mang nhiệm vụ chỉ cặn kẽ từng lệnh một. Ví dụ nếu nắm khái quát giải thuật hoán vị thì một người lập trình có đầu óc sẽ hiểu hướng giải quyết thế nào để hoán đổi giá trị của A với B dù cho chúng có là số, chuỗi, mảng, file... gì đi chăng nữa.
Còn để hiểu tại sao ít dùng từ thuật toán (Algorithm) thì các bạn cứ thử thống kê số lần xuất hiện của thuật ngữ này cũng như cách dùng thuật ngữ này trong các tài liệu nói về lập trình bất kỳ nào nhé.
Nếu tôi không lầm thì bạn hiểu thuật toán giống như tôi.
Trước hết cần hiểu chữ "Toán" trong "Thuật toán" không hẳn là Toán (học). Cách nói của người Việt là vậy. Vd. khi nói về một vấn đề khó nào đó trong một lĩnh vực sống nào đó người ta nói: "Đây là một bài toán khó cần giải quyết gấp rút". Không có nghĩa là trong đó có bài Toán khó nào đó.
Thuật toán là thuật toán. Thuật toán không phụ thuộc vào ngôn ngữ lập trình. Thậm chí không hẳn là dính dáng tới lập trình. Nói nôm na thì thuật toán là "các bước đi tuần tự hữu hạn để đạt được kết quả mong muốn nào đó, để giải quyết một vấn đề nào đó trong cuộc sống". Ở đây là nói tới những bước đi chính".
Ta lấy ví dụ vấn đề "lọc duy nhất một danh sách". Thuật toán để giải quyết vấn đề này theo tôi là:
1. Lấy phần tử đầu tiên trong danh sách gốc.
2. Kiểm tra xem trong "danh sách kết quả" đã có phần tử hiện hành chưa. Nếu chưa thì thêm vào.
3. Lấy phần tử tiếp theo nếu còn.
4. Trở lại điểm 2.
Thuật toán chỉ có thế thôi. "danh sách kết quả" là gì, cấu trúc của nó thế nào? Cái này nó không thuộc về thuật toán. Cái này nó là "chi tiết kỹ thuật", là "chi tiết cụ thể". Cách giải quyết những chi tiết cụ thể thuộc về người dùng cái thuật toán đó.
Vd. nếu người giải quyết vấn đề biết lập trình thì anh ta sẽ dùng một cấu trúc dữ liệu nào đó, các cấu trúc ngôn ngữ nào đó để thực hiện những chi tiết của từng bước đi cụ thể. Anh A có thể dùng dictionary làm "danh sách kết quả" và lúc đó anh ta dùng Exists để kiểm tra và dùng Add để thêm vào. Cũng cùng một thuật toán nhưng anh B lại dùng mảng làm "danh sách kết quả", và lúc đó anh ta phải dùng vd. vòng FOR để kiểm tra xem phần tử đã có trong "danh sách kết quả" chưa. Anh C cũng dùng mảng làm "danh sách kết quả" nhưng có vẻ kết nàng "Do...Loop" nên dùng nàng thay cho anh FOR.
Như thế cũng cùng là những bước của thuật toán nhưng các chi tiết cụ thể, chi tiết kỹ thuật thì mỗi người lại có thể giải quyết bằng một cách khác nhau.
Nói tổng quát thì thuật toán không phụ thuộc vào ngôn ngữ lập trình, thậm chí là không liên quan tới lập trình. Nó chỉ là các bước để giải quyết một vấn đề nào đó.
Chẳng hạn như có anh D không có máy tính mà cũng chả biết lập trình. Nhưng anh D hoàn toàn có thể thực hiện các bước của thuật toán để có được danh sách duy nhất. Lúc đó anh D sẽ dùng "sổ tay", "tờ giấy" làm "danh sách kết quả". Và kiểm tra tồn tại bằng cách dò bằng mắt "sổ tay, "tờ giấy". Hoặc nếu có thư ký thì lệnh cho cô thư ký làm việc này. Nếu anh D có sẵn thuật toán sắp xếp thì anh ta cũng sẽ làm và có được danh sách được sắp xếp. Dùng máy tính chẳng qua vì máy tính thao tác cực nhanh và không nhầm lẫn như con người. Thế thôi. Anh D có thể làm 1 năm, 10 năm để có được danh sách được sắp xếp nhưng ở đây cần nhấn mạnh là thuật toán chỉ là các bước hữu hạn để giải quyết một vấn đề nào đó. Bất cứ ai dùng bất cứ công cụ gì - máy tính, xẻng cuốc, bút ... - chỉ cần dùng cái thuật toán "kia" là giải quyết được vấn đề.
Thì thấy ngay thôi. Máy tính, lập trình có từ bao giờ? Còn trong cuộc sống, trong mỗi lĩnh vực, con người từ thủa biết đi đã nghĩ ra từng ngày những thuật toán lớn, nhỏ để giải quyết những vấn đề trong cuộc sống.
Nhưng đã nói tới lập trình thì chắc chắn có thuât toán. Vì người lập trình chẳng qua là chọn cấu trúc dữ liệu, chọn cấu trúc ngôn ngữ, và dùng các hàm để mã một thuật toán sao cho máy có thể hiểu được và thực hiện các bước của thuật toán kia. Tất nhiên mọi chi tiết kỹ thuật thì tùy người mà chúng được giải quyết theo cách khác nhau. Có người giải quyết tốt hơn người kia.
Tóm lại viết code hay lập công thức thì bước đầu tiên bao giờ cũng phải là tìm ra được thuật toán. Bước kế tiếp mới là tìm các công cụ thích hợp (cấu trúc dữ liệu, cấu trúc ngôn ngữ, các hàm có sẵn ...) để thực hiện các bước đã được xác định ở điểm 1. Nhiều khi cũng cùng một hướng đi, một thuật toán nhưng rất có thể 3 người cho 3 công thức khác nhau vì họ dùng các hàm khác nhau vd. để cắt chuỗi (chi tiết kỹ thuật)
Nhiều khi một người biết viết code, tức nắm chắc ngôn ngữ, sử dụng nhuần nhuyễn các cấu trúc dữ liệu, cấu trúc ngôn ngữ, có thể viết mọi code khi có được thuật toán nhưng bản thân anh ta lại rất kém về thuật toán. Nó cũng giống như một anh chàng B chưa hẳn đã được ăn học như anh A nhưng gặp những vấn đề trong cuộc sống anh ta có thể chỉ ra được các bước cần làm để giải quyết vấn đề đó trong khi anh A thì bó tay. Với những người này thì bạn
VetMini chỉ cần cho họ thuật toán. Nhưng nếu gặp những người bí về hướng đi mà lập trình trong VBA thì cũng mới chỉ bắt đầu từ "hôm qua" thì bạn cho thuật toán thôi vẫn chưa đủ.
Nói cho cùng thì để nắm được các cơ bản trong lập trình thì chỉ cần 1, 2 tuần. Để sử dụng thạo các cấu trúc dữ liệu, cấu trúc ngôn ngữ thì có thể vài tháng. Nhưng đã nói về thuật toán thì cần cù chưa đủ. Phải luyện tư duy. Tất nhiên cũng có cái phải đọc, phải học, nhưng phải luyện tư duy, tích lũy kinh nghiệm. Với mỗi vấn đề phải ngồi và viết ra giấy được các bước chính cần phải làm để giải quyết vấn đề. Tức phải nghĩ ra được thuật toán. Còn sau đó thực hiện bằng tay hay bằng máy thì tùy.