[Lập trình C] In dãy số Fibonacci

Tuesday, February 11, 2025
Edit this post


Chào các bạn. Đây là một câu hỏi phỏng vấn mình mới gặp hôm qua cho vị trí Senior Automation Engineer. Câu này mình chưa làm bao giờ, và tiếc là hôm qua bị bất ngờ, kèm thêm giới hạn thời gian nên mình đã không nghĩ ra được giải pháp. Mình vẫn cần cải thiện về mặt tâm lý khá nhiều để vượt qua được những áp lực thời gian như thế. Cũng may, đây chỉ là một phần rất nhỏ trong buổi phỏng vấn nên về tổng thể, mọi thứ vẫn ổn. Sau mỗi buổi phỏng vấn, mình có thói quen review lại các câu phỏng vấn mà mình trả lời chưa tốt để có thể làm tốt hơn cho những lần tiếp theo.

Khi đã bình tĩnh, thì mình đã có thể giải được câu hỏi này, dù giải pháp chưa thật sự tốt. Đề bài yêu cầu như sau: In ra n số Fibonacci ra console, đơn giản vậy thôi. Ví dụ, nếu n = 10 thì in ra: 1 2 3 5 8 13 21 34 55 89.

Định nghĩa: Dãy Fibonacci là một dãy số nổi tiếng trong toán học, được đặt theo tên của nhà toán học người Ý Leonardo Fibonacci. Dãy Fibonacci bắt đầu từ hai số 0 và 1 (hoặc 1 và 1 tùy theo cách định nghĩa), và các số tiếp theo được tạo ra bằng cách cộng hai số liền trước đó.

Dựa vào định nghĩa trên, với dãy Fibonacci bắt đầu từ số 1 và 2, các số tiếp theo được tính như sau: 1+2=3, 2+3=5, 3+5=8 v.v... 

Sau một hồi suy nghĩ, mình viết được đoạn code như sau bằng Java, sử dụng ArrayList với khởi tạo ban đầu chứa sẵn 2 số 1 và 2; các số tiếp theo được tính toán dựa trên tổng của 2 số liền kề trước đó:

import java.util.ArrayList;

public class Main
{
	public static void main(String[] args) {
		var n = 10;
		var numbers = new ArrayList<Integer>();
		numbers.add(1);
		numbers.add(2);

		for (var i = 2; i < 10; i++) {
			var nextNumber = numbers.get(i - 1) + numbers.get(i - 2);
			numbers.add(nextNumber);
		}

		for (var number : numbers) {
			System.out.print(number + " ");
		}
	}
}

Dù kết quả chạy ra đúng, mình vẫn tự nhận thấy cách làm này quá cồng kềnh. Về bản chất, đây là một câu hỏi về kỹ thuật lập trình, nên theo mình, chúng ta cần hạn chế sử dụng những thứ liên quan tới cấu trúc dữ liệu mà chỉ nên xoay quanh những toán tử và vòng lặp cơ bản mà thôi. Không sao, ít nhất chúng ta đã có một giải pháp ở đây, việc tiếp theo cần làm là cải tiến giải pháp này.

Đầu tiên, ở đây có 2 vòng lặp, mình sẽ tìm cách giảm xuống còn 1, tức là bằng cách nào đó để khi vừa tính toán ra số kế tiếp thì chúng ta in nó ra luôn. Và nếu đã in được số ra luôn thì có lẽ không cần tới ArrayList làm gì nữa.

Vậy, có thể dùng 2 biến để chứa 2 giá trị ban đầu (1 và 2) thay cho mảng. Trong vòng lặp, ngay sau khi tính được số tiếp theo, chúng ta sẽ cập nhật giá trị 2 biến này "ngay tại chỗ", đồng thời in kết quả ra màn hình. Với suy nghĩ như trên, một phiên bản tốt hơn của bài tập đã được viết lại như bên dưới:

public class Main
{
	public static void main(String[] args) {
		var n = 10;
		var a = 1;
		var b = 2;
		System.out.print(a + " ");
		System.out.print(b + " ");

		for (var i = 2; i < n; i++) {
			var nextNumber = a + b;
			a = b;
			b = nextNumber;
			System.out.print(nextNumber + " ");
		}
	}
}

Như ý tưởng ban đầu:
- Hai biến a và b sẽ được khởi tạo lần lượt các giá trị 1 và 2, và sẽ được in ra ngay sau khi khởi tạo. 
- Vòng lặp vẫn bắt đầu từ i=2 (tương ứng với số thứ 3), đơn giản vì hai số đầu tiên đã có. 
- Số tiếp theo (nextNumber) được tính bằng tổng của a và b.
- Giá trị của b được gán lại cho a.
- Và giá trị của nextNumber được gán lại cho b, chuẩn bị sẵn sàng cho vòng lặp tiếp theo.

Và cuối cùng, hãy viết lại đoạn code của chúng ta sang C nhé:

#include <stdio.h>

int main() {
    int n = 10;
    int a = 1, b = 2;
    printf("%d ", a);
    printf("%d ", b);

    for (int i = 2; i < n; i++) {
        int nextNumber = a + b;
        a = b;
        b = nextNumber;
        printf("%d ", nextNumber);
    }
    return 0;
}

Trên đây là một ví dụ đơn giản về cách tạo và in ra dãy Fibonacci bằng ngôn ngữ Java. Qua bài tập này, chúng ta không chỉ hiểu rõ hơn về cách hoạt động của dãy Fibonacci mà còn thấy được sự linh hoạt của vòng lặp và cách quản lý biến trong lập trình. Dãy Fibonacci không chỉ là một khái niệm toán học thú vị mà còn có nhiều ứng dụng thực tế trong khoa học máy tính, tài chính, và cả nghệ thuật. Hãy thử thay đổi giá trị của n hoặc khởi tạo dãy với các số khác nhau để khám phá thêm nhé! Chúc bạn có những trải nghiệm thú vị khi lập trình!

.
Xin vui lòng chờ đợi
Dữ liệu bài viết đang được tải về

💻Nhận hướng dẫn online 1 kèm 1 Automation Test từ cơ bản tới nâng cao (From Zero to Hero) 😁😁😁
Lộ trình gồm 3 phần:
1) Kỹ thuật lập trình và tư duy lập trình cơ bản
2) Nhập môn kiểm thử (Manual Test)
3) Kiểm thử tự động (Automation Test) + Chuẩn bị cho phỏng vấn
* Lộ trình tham khảo khoảng 30 buổi: Xem tại đây (thời gian học thực tế có thể ngắn hơn hoặc dài hơn tùy vào mỗi cá nhân người học)

🎓Đối tượng người học:
- Những bạn bị mất gốc căn bản môn lập trình.
- Những bạn muốn theo con đường kiểm thử (testing), đặc biệt là kiểm thử tự động (Automation Test).

🦘Người hướng dẫn:
- Mình sẽ là người trực tiếp hướng dẫn.
- Nếu là các vấn đề ngoài chuyên môn hoặc sở trường, mình sẽ nhờ các anh chị em khác cũng làm trong ngành.

🤓Giới thiệu:
- Mình đã có hơn 10 năm kinh nghiệm làm IT ở cả trong và ngoài nước. Trong đó 3 năm đầu là làm lập trình viên Java, sau đó bén duyên với mảng Automation Test và theo nghề tới tận bây giờ. Mình được đào tạo chính quy về IT từ một trường Đại học danh tiếng ở TP.HCM (hệ kỹ sư 4 năm rưỡi), có chứng chỉ ISTQB, có thể giao tiếp tốt bằng tiếng Anh và có kinh nghiệm làm việc thực tế ở cả 2 mảng Outsource và Product. Title chính thức của mình là QA Automation Engineer, tuy nhiên, mình vẫn làm những dự án cá nhân chuyên về lập trình ứng dụng như Học Tiếng Anh StreamlineSách Nhạc. Mình là người có thái độ làm việc chuyên nghiệp, chăm chỉ và luôn nhiệt tình trong công việc.

💵Chi phí và hình thức thanh toán:
- Các bạn vui lòng liên hệ qua email songtoigianvn@gmail.com để book nội dung và khung giờ học.
- Mức phí: 150.000đ/buổi, mỗi buổi 60 phút. Có thể thanh toán mỗi lần cho 5 buổi.
- Thanh toán qua Momo, chuyển khoản v.v...
BÌNH LUẬN
© Copyright by CUỘC SỐNG TỐI GIẢN
Loading...