Java Bài 10: Các Câu Lệnh Nhảy (break Và continue) Trong Vòng Lặp

Posted by

Nội dung bài viết

Được chỉnh sửa ngày 6/9/2017.

Chào mừng các bạn quay lại với bài học Java thứ 10 trong chuỗi bài viết về lập trình ngôn ngữ Java của Yellow Code Book.

Mình xin giải thích một chút ý nghĩa của bài hôm nay. Bài học hôm nay đáng lý ra phải nằm ở bài 9 – Bài nói về các câu lệnh lặp – Vì kiến thức của bài hôm nay có liên quan các câu lệnh lặp đó.

Tuy nhiên mình nghĩ nếu nói về kiến thức này ở bài trước sẽ làm cho bài học bị dài ra, vừa khó để các bạn nhớ, vừa khó để thực hành, lại khó cho mình khi phải viết một bài quá dài. Chính vì vậy mình tách ra thành một bài học hôm nay.

Chúng ta sẽ nói đến 2 câu lệnh nhảy trong bài hôm nay, đó là breakcontinue. Trong khi có một câu lệnh nhảy khác là return sẽ được trao đổi ở bài viết về Phương Thức sau nhé.

Sở dĩ Java dùng từ “nhảy” không phải vì nó làm cho các vòng lặp của bạn thêm nhảy nhót. Nhảy ở đây là nhảy ra khỏi vòng lặp, hay nhảy đến một lần lặp tiếp theo mà bỏ qua các câu lệnh còn lại bên trong thân vòng lặp đó. Một số tài liệu khác gọi đây là Các câu lệnh điều khiển, nhưng mình thích từ nhảy hơn, tiếng Việt nghe hơi chuối nhưng tiếng Anh họ gọi là Jump Statements, nghe rõ nghĩa hơn.

Chúng ta cùng xem qua nhé.

break – Câu Lệnh Dừng

Bạn hiểu nghĩa breakđập vỡ cũng đúng, nhưng trong tình huống này nó có nghĩa là dừng thì hay hơn.

Theo đúng tên gọi, khi câu lệnh này xuất hiện ở đâu đó trong vòng lặp, chúng sẽ làm phá vỡ, hay dừng vòng lặp đó dù cho vẫn còn các câu lệnh khác bên trong vòng lặp chưa được xử lý.

Nếu bạn còn nhớ, ở bài 8 chúng ta cùng nói qua câu lệnh break này cho cấu trúc switch case đúng không nào. Vâng, breakswitch case break ở câu lệnh lặp cũng có công dụng tương tự như nhau thôi.

Bài Thực Hành Số 1

Bài thực hành này muốn bạn in ra console tất cả các số nguyên tố từ 1 đến 10.000.

Khoan! Có gì đó sai sai! In số nguyên tố đã được thực hành ở bài trước rồi mà! Và in số nguyên tố thì có liên quan gì đến break!?!

Bạn yên tâm, in số nguyên tố ở bài trước chỉ là một giải thuật gà. Trong lập trình, đặc biệt là lập trình các thuật toán, sẽ luôn luôn hoan nghênh các bạn có những giải thuật cải tiến sao cho ứng dụng chạy nhanh, mượt. Muốn được như vậy thì các thuật toán của các bạn phải gọn, bắt máy tính làm việc ít hơn, số lượng vòng lặp giảm thiểu,… Có lẽ chúng ta sẽ nói đến chủ đề này ở bài khác.

Quay lại bài thực hành, chúng ta sẽ cải tiến giải thuật tìm số nguyên tố, kết hợp với câu lệnh break để dừng việc kiểm tra sớm một khi đã biết số đó không phải là số nguyên tố.

Bạn đã biết số nguyên tố là số chỉ chia hết cho 1 và chính nó. Để làm vậy, với cách cũ bạn duyệt qua các số hạng từ 1 đến chính nó, đếm xem có bao nhiêu số hạng mà nó chia hết cho, nếu đếm thấy 2 số hạng thì nó đúng là số nguyên tố. Với cách này bạn luôn phải cho vòng lặp chạy hết tất cả các số hạng. Cụ thể, với việc kiểm tra số 10.000, thì ứng dụng của bạn sẽ phải lặp 10.000 lần để đếm. Cách này mình đo thấy ứng dụng tốn 376 ms (mili giây) để chạy, tức là gần nửa giây. Bạn có thể áp dụng break vào việc giảm số lần lặp bằng 2 cách sau.

– Đừng cho vòng lặp chạy từ 1 đến chính nó, mà hãy cho vòng lặp chạy từ số 2 đến chính nó giảm đi 1 đơn vị, tức là chạy trong khoảng [2, chính nó). Hễ tìm được một số nào đó trong khoảng này mà chính nó chia hết, gọi lệnh break ngay để kết thúc lặp, không cần lặp nữa vì chắc chắn nó không phải số nguyên tố. Với giải thuật này thì giả sử để kiểm tra số 10.000, ứng dụng của bạn chỉ cần chạy đến số hạng 2 là đã break rồi. Cách này tốn 167 ms để in ra hết các số nguyên tố, chỉ tốn một nửa thời gian so với cách thứ nhất. Ôi cool quá!

– Cách này hay hơn nữa, theo nghiên cứu (chưa rõ từ nguồn nào) thì bạn chỉ cần kiểm tra trong khoảng 2 đến căn bậc hai của chính nó, tức là cho vòng lặp chạy trong khoảng [2, căn bậc 2 chính nó]. Nếu tìm thấy một số trong khoảng này mà nó chia hết cho, thì nó không phải là số nguyên tố. Trong Java, hàm lấy căn bậc hai một số là Math.sqrt(số_thực);. Giải thuật thứ ba này chỉ mất có 15 ms để chạy thôi nhé, nhanh gấp 25 lần so với cách thứ nhất.

Mình áp dụng cách chạy nhanh nhất trên đây vào code bên dưới, bạn áp dụng cách nào? Hãy thử code nhé.

for (int number = 2; number <= 10000; number++) {
	boolean isPrime = true; // Thay vì biến count, dùng biến này để kiểm tra số nguyên tố
	for(int j = 2; j <= Math.sqrt(number); j++) {
		if (number % j == 0) {
			// Chỉ cần một giá trị được tìm thấy trong khoảng này,
			// thì number không phải số nguyên tố
			isPrime = false;
			break; // Thoát ngay và luôn khỏi for (vòng for bên ngoài vẫn chạy)
		}
	}
	if (isPrime) {
		// Nếu isPrime còn giữ được sự "trong trắng" đến cùng thì đó là số nguyên tố
		System.out.println(number);
	}
}

continue – Câu Lệnh Bỏ Qua

Lại một lần nữa nghĩa và công dụng của từ này bị lẫn lộn. Bạn giỏi tiếng Anh nên hiểu nghĩa của continuetiếp tục cũng không sai, nhưng tình huống này chúng ta hiểu là bỏ qua.

Bỏ qua có nghĩa là bỏ các câu lệnh còn lại bên trong vòng lặp để thực hiện một chu trình lặp mới. Câu lệnh này không làm dừng vòng lặp như break, mà chỉ thực hiện vòng lặp mới, vòng lặp có thể bị dừng bởi continue khi mà việc thực hiện vòng lặp mới sẽ kiểm tra và thấy điều_kiện_lặp không còn thỏa mà thôi.

Có một lưu ý nhỏ khi bạn dùng continue cho forwhile/do while như sau. Bởi vì continue sẽ tự thực hiện một vòng lặp mới nên có khả năng biến đếm sẽ bị bỏ qua nếu bạn để câu lệnh tăng biến đếm ở sau continue, như vậy sẽ có trường hợp bạn bị rơi vào vòng lặp vô tận, điều này dễ gặp ở whiledo while. Nhưng với for thì bạn yên tâm, câu lệnh continue ở vòng lặp này bao gồm việc tăng biến đếm (nếu bạn có định nghĩa việc tăng biến đếm này ở thành phần thứ ba của for) rồi mới thực hiện vòng lặp mới nên dùng continue trong for sẽ an toàn hơn nhé.

Bài Thực Hành Số 2

Bài này bạn sẽ phải in ra console ngược lại với bài thực hành ở trên, kết hợp với continue. Bạn hãy viết chương trình in ra console tất cả các số KHÔNG PHẢI LÀ SỐ NGUYÊN TỐ trong khoảng từ 1 đến 100.

Chúng ta sẽ áp dụng giải thuật tìm số nguyên tố, hễ biết đó là số nguyên tố thì sẽ dùng continue “lướt” qua lần lặp mới, các câu lệnh in ra console sẽ để bên dưới câu lệnh continue để đảm bảo in ra những gì không thỏa điều kiện của continue. Code chúng ta như sau.

for (int number = 1; number <= 100; number++) {
	if (number == 1) {
		// 1 không phải số nguyên tố, in ra rồi biến
		System.out.println(number);
		continue;
	}

	boolean isPrime = true; // Biến kiểm tra số nguyên tố
	for(int j = 2; j <= Math.sqrt(number); j++) {
		if (number % j == 0) {
			// Chỉ cần một giá trị được tìm thấy trong khoảng này,
			// thì number không phải số nguyên tố
			isPrime = false;
			break; // Thoát ngay và luôn khỏi for (vòng for bên ngoài vẫn chạy)
		}
	}

	if (isPrime) {
		// Nếu isPrime cho biết đây là số nguyên tố
		// bỏ qua câu lệnh dưới đây mà qua lần lặp kế
		continue;
	}

	System.out.println(number);
}

Bạn vừa cùng mình đi qua các câu lệnh còn lại có ảnh hưởng đến cấu trúc lặp mà các bạn vừa học qua.

Cảm ơn bạn đã đọc các bài viết của Yellow Code Books. Bạn hãy đánh giá 5 sao nếu thấy thích bài viết, hãy comment bên dưới nếu có thắc mắc, hãy để lại địa chỉ email của bạn để nhận được thông báo mới nhất khi có bài viết mới, và nhớ chia sẻ các bài viết của Yellow Code Books đến nhiều người khác nữa nhé.

Bài Kế Tiếp

Chúng ta sẽ cùng nhau tìm hiểu về Mảng trong Java nhé.

Advertisements
Rating: 5.0. From 3 votes.
Please wait...

5 comments

Gửi phản hồi