So sánh không dùng vòng lặp năm 2024

Đếm số phép so sánh và hoán vị theo từng vòng, và tổng kết của thuật toán sau (n là số phần tử của mảng a):

void f(int a[], int n) { int i, j; for (int i = 0; i < n-1; i++) { for (int j = i; j < n; j++) { if (a[i] < a[j]) { int temp = a[i]; a[i] = a[j]; a[j] = temp; } } } }

Đây là một dạng của thuật toán sắp xếp, cụ thể là Sắp xếp chọn (Selection Sort). Dưới đây là phân tích số phép hoán vị và phép so sánh:

  1. Phép so sánh:
  2. Vòng lặp thứ nhất chạy từ i=0 đến n-1.
  3. Vòng lặp thứ hai bên trong vòng lặp thứ nhất chạy từ j=i+1 đến n.

Vì vậy, số tổng số phép so sánh sẽ là (n-1) + (n-2) + ... + 2 + 1 = n(n-1)/2. Đây cũng chính là công thức của tổ hợp chập 2 của n.

  1. Phép hoán vị:

Ở mỗi lần lặp, nếu phần tử a[i] nhỏ hơn a[j] thì sẽ thực hiện hoán vị. Trong trường hợp xấu nhất (mảng đầu vào sắp xếp giảm dần), mỗi vòng lặp của 'j' sẽ phải thực hiện một hoán vị.

Tương tự như số phép so sánh, số phép hoán vị cũng sẽ là n(n-1)/2.

Nhưng nếu đầu vào là một mảng đã sắp xếp tăng dần (trường hợp tốt nhất), thì không cần phép hoán vị nào cả.

Nói chung, số phép hoán vị phụ thuộc vào đầu vào, nên không thể xác định chính xác cho mọi trường hợp.

Hãy nhớ rằng, đôi khi lựa chọn thuật toán tối ưu phụ thuộc nhiều vào dữ liệu đầu vào. Nhưng không sao cả, nếu bạn gặp khó khăn trong việc hiểu các loại thuật toán, ghé thăm trituenhantao.io để tìm hiểu thêm. Đừng để một hoá đơn phức tạp khiến bạn mất hứng thú với lập trình!

Trong bài viết này, ta tiếp tục tìm hiểu các khía cạnh khác trong vòng lặp của Java bao gồm: Vòng lặp for lồng, vòng lặp do-while, đồng thời tìm hiểu xem khi nào sử dụng for, khi nào sử dụng while, cuối cùng ta làm quen về 2 keyword thường được sử dụng trong vòng lặp là break và continue.

Vòng lặp for lồng

Vòng lặp "for" lồng (nested for loop) trong Java là một cấu trúc lặp bên trong một vòng lặp khác. Điều này cho phép bạn thực hiện các lặp lồng nhau, tức là một vòng lặp nằm bên trong một vòng lặp khác. Vòng lặp "for" lồng thường được sử dụng để thực hiện lặp lại qua tập hợp đa chiều, mảng hai chiều hoặc thực hiện các phép toán lặp lồng nhau khác.

Cấu trúc cơ bản của vòng lặp "for" lồng trong Java có thể được thể hiện như sau:

for (int i = 0; i < outerLimit; i++) {
    // code thực thi trong vòng lặp ngoài
    for (int j = 0; j < innerLimit; j++) {
        // code thực thi trong vòng lặp bên trong
    }
}

Trong trường hợp này:

  • public class NestedForLoopExample {

    public static void main(String[] args) {  
        for (int i = 1; i <= 3; i++) {  
            for (int j = 1; j <= 3; j++) {  
                System.out.println("i: " + i + ", j: " + j);  
            }  
        }  
    }  
    
    }

    3: Đây là vòng lặp bên ngoài, nó sẽ thực hiện các lệnh lặp qua một tập hợp hoặc mảng bên ngoài.

    public class NestedForLoopExample {

    public static void main(String[] args) {  
        for (int i = 1; i <= 3; i++) {  
            for (int j = 1; j <= 3; j++) {  
                System.out.println("i: " + i + ", j: " + j);  
            }  
        }  
    }  
    
    }

    4 là biến đếm của vòng lặp này.
  • public class NestedForLoopExample {

    public static void main(String[] args) {  
        for (int i = 1; i <= 3; i++) {  
            for (int j = 1; j <= 3; j++) {  
                System.out.println("i: " + i + ", j: " + j);  
            }  
        }  
    }  
    
    }

    5: Đây là vòng lặp bên trong, nó nằm bên trong vòng lặp bên ngoài. Nó sẽ thực hiện các lệnh lặp qua một tập hợp hoặc mảng bên trong.

    public class NestedForLoopExample {

    public static void main(String[] args) {  
        for (int i = 1; i <= 3; i++) {  
            for (int j = 1; j <= 3; j++) {  
                System.out.println("i: " + i + ", j: " + j);  
            }  
        }  
    }  
    
    }

    6 là biến đếm của vòng lặp này.

Vòng lặp "for" lồng là một công cụ mạnh mẽ cho việc thực hiện các phép toán lặp lồng nhau, ví dụ như duyệt qua các ma trận, tập hợp lồng nhau hoặc xử lý các cấu trúc dữ liệu đa chiều. Tuy nhiên, hãy cẩn thận với việc sử dụng vòng lặp lồng, vì chúng có thể làm tăng độ phức tạp của code và làm cho code trở nên khó hiểu hơn nếu không được quản lý cẩn thận.

Ví dụ 1

Ví dụ về vòng lặp "for" lồng:

public class NestedForLoopExample {
    public static void main(String[] args) {
        for (int i = 1; i <= 3; i++) {
            for (int j = 1; j <= 3; j++) {
                System.out.println("i: " + i + ", j: " + j);
            }
        }
    }
}

Kết quả của chương trình này sẽ là một danh sách các cặp giá trị

public class NestedForLoopExample {
    public static void main(String[] args) {
        for (int i = 1; i <= 3; i++) {
            for (int j = 1; j <= 3; j++) {
                System.out.println("i: " + i + ", j: " + j);
            }
        }
    }
}

4 và

public class NestedForLoopExample {
    public static void main(String[] args) {
        for (int i = 1; i <= 3; i++) {
            for (int j = 1; j <= 3; j++) {
                System.out.println("i: " + i + ", j: " + j);
            }
        }
    }
}

6 khi cả hai biến đều chạy từ 1 đến 3. Vòng lặp bên trong được thực hiện mỗi lần vòng lặp bên ngoài chạy. Kết quả sẽ là:

i: 1, j: 1
i: 1, j: 2
i: 1, j: 3
i: 2, j: 1
i: 2, j: 2
i: 2, j: 3
i: 3, j: 1
i: 3, j: 2
i: 3, j: 3

Ví dụ 2

Vòng lặp "for" lồng thường xuất hiện trong bài toán quy hoạch động khi bạn cần tính toán giá trị tại một ô cụ thể trong ma trận dựa trên giá trị của các ô lân cận. Dưới đây là một ví dụ về việc sử dụng vòng lặp "for" lồng trong bài toán quy hoạch động để tìm giá trị lớn nhất của một dãy con tăng dài nhất trong một mảng.

Bài toán: Tìm dãy con tăng dài nhất trong mảng.

Giải thuật quy hoạch động:

  1. Tạo một mảng

    public class NestedForLoopExample {

    public static void main(String[] args) {  
        for (int i = 1; i <= 3; i++) {  
            for (int j = 1; j <= 3; j++) {  
                System.out.println("i: " + i + ", j: " + j);  
            }  
        }  
    }  
    
    }

    9 với cùng độ dài như mảng ban đầu và khởi tạo mọi phần tử bằng 1. Mảng

    public class NestedForLoopExample {

    public static void main(String[] args) {  
        for (int i = 1; i <= 3; i++) {  
            for (int j = 1; j <= 3; j++) {  
                System.out.println("i: " + i + ", j: " + j);  
            }  
        }  
    }  
    
    }

    9 sẽ lưu trữ độ dài của dãy con tăng dài nhất kết thúc tại vị trí đó.
  2. Duyệt qua mảng ban đầu từ đầu đến cuối (sử dụng vòng lặp "for").
  3. Trong mỗi lần lặp, duyệt qua tất cả các phần tử trước đó (sử dụng vòng lặp "for" lồng). So sánh phần tử hiện tại với các phần tử trước đó. Nếu phần tử hiện tại lớn hơn phần tử trước đó và độ dài dãy con tăng kết thúc tại phần tử hiện tại cộng thêm 1 lớn hơn giá trị lưu trong mảng

    public class NestedForLoopExample {

    public static void main(String[] args) {  
        for (int i = 1; i <= 3; i++) {  
            for (int j = 1; j <= 3; j++) {  
                System.out.println("i: " + i + ", j: " + j);  
            }  
        }  
    }  
    
    }

    9, thì cập nhật giá trị trong mảng

    public class NestedForLoopExample {

    public static void main(String[] args) {  
        for (int i = 1; i <= 3; i++) {  
            for (int j = 1; j <= 3; j++) {  
                System.out.println("i: " + i + ", j: " + j);  
            }  
        }  
    }  
    
    }

    9.
  4. Cuối cùng, tìm giá trị lớn nhất trong mảng

    public class NestedForLoopExample {

    public static void main(String[] args) {  
        for (int i = 1; i <= 3; i++) {  
            for (int j = 1; j <= 3; j++) {  
                System.out.println("i: " + i + ", j: " + j);  
            }  
        }  
    }  
    
    }

    9, đó chính là độ dài của dãy con tăng dài nhất.

Dưới đây là code Java thực hiện bài toán này:

public class LongestIncreasingSubsequence {
    public static int findLengthOfLIS(int[] nums) {
        if (nums == null || nums.length == 0) {
            return 0;
        }
        int[] dp = new int[nums.length];
        int maxLength = 1; // Độ dài của dãy con tăng dài nhất, ít nhất là 1
        for (int i = 0; i < nums.length; i++) {
            dp[i] = 1; // Khởi tạo độ dài tại vị trí i bằng 1
            for (int j = 0; j < i; j++) {
                if (nums[i] > nums[j] && dp[i] < dp[j] + 1) {
                    dp[i] = dp[j] + 1;
                }
            }
            maxLength = Math.max(maxLength, dp[i]);
        }
        return maxLength;
    }
    public static void main(String[] args) {
        int[] nums = {10, 22, 9, 33, 21, 50, 41, 60, 80};
        int longestLength = findLengthOfLIS(nums);
        System.out.println("Độ dài của dãy con tăng dài nhất là: " + longestLength);
    }
}

Trong ví dụ này:

  • ta sử dụng vòng lặp "for" ngoài để duyệt qua từng phần tử của mảng

    i: 1, j: 1 i: 1, j: 2 i: 1, j: 3 i: 2, j: 1 i: 2, j: 2 i: 2, j: 3 i: 3, j: 1 i: 3, j: 2 i: 3, j: 3

    4.
  • ta sử dụng vòng lặp "for" lồng bên trong để so sánh phần tử hiện tại

    i: 1, j: 1 i: 1, j: 2 i: 1, j: 3 i: 2, j: 1 i: 2, j: 2 i: 2, j: 3 i: 3, j: 1 i: 3, j: 2 i: 3, j: 3

    5 với các phần tử trước đó

    i: 1, j: 1 i: 1, j: 2 i: 1, j: 3 i: 2, j: 1 i: 2, j: 2 i: 2, j: 3 i: 3, j: 1 i: 3, j: 2 i: 3, j: 3

    6 và cập nhật độ dài dãy con tăng tại

    public class NestedForLoopExample {

    public static void main(String[] args) {  
        for (int i = 1; i <= 3; i++) {  
            for (int j = 1; j <= 3; j++) {  
                System.out.println("i: " + i + ", j: " + j);  
            }  
        }  
    }  
    
    }

    4 nếu thỏa coden điều kiện tăng.
  • Cuối cùng, ta tìm giá trị lớn nhất trong mảng

    public class NestedForLoopExample {

    public static void main(String[] args) {  
        for (int i = 1; i <= 3; i++) {  
            for (int j = 1; j <= 3; j++) {  
                System.out.println("i: " + i + ", j: " + j);  
            }  
        }  
    }  
    
    }

    9, đó chính là độ dài của dãy con tăng dài nhất.

Kết quả của chương trình sẽ là độ dài của dãy con tăng dài nhất trong mảng đầu vào.

Ví dụ 3

Vòng lặp for lồng thường xuất hiện trong ứng dụng thực tế khi bạn cần duyệt qua các phần tử trong mảng hai chiều (hoặc nhiều chiều hơn), thực hiện các phép toán trên mảng hoặc tìm kiếm thông tin phù hợp với một mô hình phức tạp hơn. Dưới đây là một ví dụ về việc sử dụng vòng lặp for lồng trong ứng dụng thực tế để tính điểm trung bình của học sinh trong một lớp học.

Bài toán: Tính điểm trung bình của học sinh trong một lớp học.

Giải thuật:

  1. Tạo một mảng hai chiều để lưu trữ điểm của các học sinh. Mỗi hàng của mảng đại diện cho một học sinh và mỗi cột đại diện cho một môn học.
  2. Duyệt qua từng học sinh (hàng) bằng một vòng lặp "for" ngoài.
  3. Bên trong vòng lặp "for" ngoài, sử dụng một vòng lặp "for" lồng để duyệt qua từng môn học (cột) và tính tổng điểm của học sinh đó.
  4. Tính điểm trung bình bằng cách chia tổng điểm cho số môn học.

Dưới đây là code Java thực hiện bài toán này:

public class CalculateStudentAverage {
    public static void main(String[] args) {
        int[][] scores = {
            {85, 90, 88},
            {92, 88, 78},
            {78, 92, 94},
            {89, 76, 84}
        };
        int numStudents = scores.length;
        int numSubjects = scores[0].length;
        double[] averages = new double[numStudents];
        for (int i = 0; i < numStudents; i++) {
            int total = 0;
            for (int j = 0; j < numSubjects; j++) {
                total += scores[i][j];
            }
            averages[i] = (double) total / numSubjects;
        }
        for (int i = 0; i < numStudents; i++) {
            System.out.println("Học sinh " + (i + 1) + " - Điểm trung bình: " + averages[i]);
        }
    }
}

Trong ví dụ này:

  • ta có một mảng hai chiều

    i: 1, j: 1 i: 1, j: 2 i: 1, j: 3 i: 2, j: 1 i: 2, j: 2 i: 2, j: 3 i: 3, j: 1 i: 3, j: 2 i: 3, j: 3

    9 để lưu trữ điểm của các học sinh. Mỗi hàng của mảng đại diện cho một học sinh và mỗi cột đại diện cho một môn học.
  • ta duyệt qua từng học sinh bằng vòng lặp "for" ngoài (biến

    public class NestedForLoopExample {

    public static void main(String[] args) {  
        for (int i = 1; i <= 3; i++) {  
            for (int j = 1; j <= 3; j++) {  
                System.out.println("i: " + i + ", j: " + j);  
            }  
        }  
    }  
    
    }

  • và bên trong, sử dụng vòng lặp "for" lồng (biến

    public class NestedForLoopExample {

    public static void main(String[] args) {  
        for (int i = 1; i <= 3; i++) {  
            for (int j = 1; j <= 3; j++) {  
                System.out.println("i: " + i + ", j: " + j);  
            }  
        }  
    }  
    
    }

  • để duyệt qua từng môn học và tính tổng điểm của học sinh đó.
  • Cuối cùng, ta tính điểm trung bình của từng học sinh bằng cách chia tổng điểm cho số môn học (

    public class LongestIncreasingSubsequence {

    public static int findLengthOfLIS(int[] nums) {  
        if (nums == null || nums.length == 0) {  
            return 0;  
        }  
        int[] dp = new int[nums.length];  
        int maxLength = 1; // Độ dài của dãy con tăng dài nhất, ít nhất là 1  
        for (int i = 0; i < nums.length; i++) {  
            dp[i] = 1; // Khởi tạo độ dài tại vị trí i bằng 1  
            for (int j = 0; j < i; j++) {  
                if (nums[i] > nums[j] && dp[i] < dp[j] + 1) {  
                    dp[i] = dp[j] + 1;  
                }  
            }  
            maxLength = Math.max(maxLength, dp[i]);  
        }  
        return maxLength;  
    }  
    public static void main(String[] args) {  
        int[] nums = {10, 22, 9, 33, 21, 50, 41, 60, 80};  
        int longestLength = findLengthOfLIS(nums);  
        System.out.println("Độ dài của dãy con tăng dài nhất là: " + longestLength);  
    }  
    
    }

    2).
  • Kết quả là danh sách điểm trung bình của từng học sinh.

Vòng lặp for lồng trong ví dụ này cho phép ta duyệt qua cả mảng hai chiều và thực hiện các phép tính phức tạp dựa trên giá trị của từng ô trong mảng, trong trường hợp này là tính điểm trung bình của học sinh.

So sánh vòng lặp for và while

Vòng lặp "for" và "while" là hai cấu trúc lặp phổ biến trong ngôn ngữ lập trình Java, và mỗi loại có mục đích và ưu điểm riêng của nó. Dưới đây, ta sẽ so sánh vòng lặp "for" và "while" dựa trên một số yếu tố khác nhau.

Vòng lặp "for":

  1. Sử dụng khi bạn biết trước số lần lặp: Vòng lặp "for" thường được sử dụng khi bạn biết chính xác số lần lặp cần thực hiện. Ví dụ, lặp qua mảng có kích thước đã biết hoặc thực hiện một số lần cố định.
  2. Dễ đọc: Cấu trúc của vòng lặp "for" rất rõ ràng, với phần khởi tạo, điều kiện và cập nhật được định rõ trong dòng lệnh. Điều này làm cho code dễ đọc và dễ hiểu hơn.
  3. Thích hợp cho các vòng lặp kiểu "đếm ngược": Vòng lặp "for" thích hợp khi bạn muốn lặp ngược từ một giá trị lớn đến giá trị nhỏ hơn (ví dụ: giảm biến đếm từ 10 đến 1).

Vòng lặp "while":

  1. Sử dụng khi số lần lặp không xác định trước: Vòng lặp "while" thường được sử dụng khi bạn không biết trước số lần lặp cần thực hiện và vòng lặp sẽ tiếp tục cho đến khi một điều kiện nhất định trở thành "false."
  2. Tùy biến điều kiện dừng: Với vòng lặp "while," bạn có sự linh hoạt cao hơn trong việc tạo điều kiện dừng, và điều kiện có thể thay đổi trong quá trình lặp.
  3. Thích hợp cho vòng lặp vô hạn: Vòng lặp "while" có thể dễ dàng tạo thành một vòng lặp vô hạn nếu bạn không chắc chắn về việc dừng nó.

Dưới đây là một ví dụ so sánh giữa vòng lặp "for" và "while" để thực hiện cùng một nhiệm vụ - in ra các số từ 1 đến 5:

Vòng lặp "for":

for (int i = 1; i <= 5; i++) {
    System.out.println(i);
}

Vòng lặp "while":

int i = 1;
while (i <= 5) {
    System.out.println(i);
    i++;
}

Cả hai ví dụ đều thực hiện công việc tương tự, nhưng bạn có thể thấy sự khác biệt trong cấu trúc và cách điều kiện được xử lý.

Tóm lại, vòng lặp "for" thường được sử dụng khi số lần lặp là cố định và rõ ràng, trong khi vòng lặp "while" thường được sử dụng khi bạn cần một điều kiện để kiểm tra và số lần lặp có thể thay đổi trong quá trình thực hiện. Việc lựa chọn giữa "for" và "while" phụ thuộc vào yêu cầu cụ thể của nhiệm vụ lập trình của bạn.

Vòng lặp do-while

Vòng lặp "do-while" là một trong những cấu trúc lặp quan trọng trong ngôn ngữ lập trình Java. Nó cho phép bạn lặp lại một chuỗi các câu lệnh một hoặc nhiều lần dựa trên một điều kiện kiểm tra. Một đặc điểm quan trọng của vòng lặp "do-while" là nó luôn thực hiện ít nhất một lần trước khi kiểm tra điều kiện. Dưới đây là một sự giới thiệu về vòng lặp "do-while":

Cú pháp của vòng lặp "do-while" trong Java:

do {
    // code thực thi trong vòng lặp
} while (điều kiện);

  • public class LongestIncreasingSubsequence {

    public static int findLengthOfLIS(int[] nums) {  
        if (nums == null || nums.length == 0) {  
            return 0;  
        }  
        int[] dp = new int[nums.length];  
        int maxLength = 1; // Độ dài của dãy con tăng dài nhất, ít nhất là 1  
        for (int i = 0; i < nums.length; i++) {  
            dp[i] = 1; // Khởi tạo độ dài tại vị trí i bằng 1  
            for (int j = 0; j < i; j++) {  
                if (nums[i] > nums[j] && dp[i] < dp[j] + 1) {  
                    dp[i] = dp[j] + 1;  
                }  
            }  
            maxLength = Math.max(maxLength, dp[i]);  
        }  
        return maxLength;  
    }  
    public static void main(String[] args) {  
        int[] nums = {10, 22, 9, 33, 21, 50, 41, 60, 80};  
        int longestLength = findLengthOfLIS(nums);  
        System.out.println("Độ dài của dãy con tăng dài nhất là: " + longestLength);  
    }  
    
    }

    3 là phần của code mà bạn muốn thực hiện lặp lại.
  • public class LongestIncreasingSubsequence {

    public static int findLengthOfLIS(int[] nums) {  
        if (nums == null || nums.length == 0) {  
            return 0;  
        }  
        int[] dp = new int[nums.length];  
        int maxLength = 1; // Độ dài của dãy con tăng dài nhất, ít nhất là 1  
        for (int i = 0; i < nums.length; i++) {  
            dp[i] = 1; // Khởi tạo độ dài tại vị trí i bằng 1  
            for (int j = 0; j < i; j++) {  
                if (nums[i] > nums[j] && dp[i] < dp[j] + 1) {  
                    dp[i] = dp[j] + 1;  
                }  
            }  
            maxLength = Math.max(maxLength, dp[i]);  
        }  
        return maxLength;  
    }  
    public static void main(String[] args) {  
        int[] nums = {10, 22, 9, 33, 21, 50, 41, 60, 80};  
        int longestLength = findLengthOfLIS(nums);  
        System.out.println("Độ dài của dãy con tăng dài nhất là: " + longestLength);  
    }  
    
    }

    4 là biểu thức kiểm tra. Nếu điều kiện là "true," vòng lặp sẽ tiếp tục lặp. Nếu điều kiện trở thành "false," vòng lặp kết thúc.

Cách hoạt động của vòng lặp "do-while":

  1. code trong khối "do" sẽ được thực hiện một lần đầu tiên mà không cần kiểm tra điều kiện.
  2. Sau khi thực hiện code trong khối "do," điều kiện kiểm tra được thực hiện.
  3. Nếu điều kiện là "true," vòng lặp sẽ tiếp tục thực hiện và lặp lại bước 1.
  4. Nếu điều kiện là "false," vòng lặp kết thúc và quá trình thực hiện tiếp theo được tiếp tục ngoài vòng lặp "do-while."

Lợi ích và trường hợp sử dụng vòng lặp "do-while":

  1. Thực hiện ít nhất một lần: Vòng lặp "do-while" rất hữu ích khi bạn cần thực hiện một tập hợp các câu lệnh ít nhất một lần trước khi kiểm tra điều kiện. Điều này đảm bảo rằng ít nhất một bước xử lý sẽ được thực hiện, ngay cả khi điều kiện ban đầu không đúng.
  2. Sử dụng cho menu và nhập liệu: "do-while" thường được sử dụng trong các tình huống liên quan đến nhập liệu và hiển thị menu trong ứng dụng. Nó đảm bảo rằng menu sẽ được hiển thị ít nhất một lần và sau đó lặp lại theo yêu cầu của người dùng.
  3. Thích hợp cho các tác vụ yêu cầu kiểm tra sau quá trình xử lý ban đầu: Nếu bạn cần thực hiện một tập hợp các câu lệnh và sau đó kiểm tra kết quả hoặc điều kiện sau quá trình xử lý ban đầu, vòng lặp "do-while" là lựa chọn lý tưởng.

Dưới đây là một ví dụ về việc sử dụng vòng lặp "do-while" để nhập và kiểm tra mật khẩu từ người dùng:

import java.util.Scanner;
public class DoWhileExample {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String password;
        do {
            System.out.print("Nhập mật khẩu: ");
            password = scanner.nextLine();
        } while (!password.equals("password123"));
        System.out.println("Chào mừng đến với hệ thống!");
    }
}

Trong ví dụ này, ta sử dụng vòng lặp "do-while" để yêu cầu người dùng nhập mật khẩu. Ngay cả khi mật khẩu không đúng ban đầu, người dùng sẽ được yêu cầu nhập lại ít nhất một lần trước khi được chào mừng vào hệ thống.

Break và continue

Trong ngôn ngữ lập trình Java,

public class LongestIncreasingSubsequence {
    public static int findLengthOfLIS(int[] nums) {
        if (nums == null || nums.length == 0) {
            return 0;
        }
        int[] dp = new int[nums.length];
        int maxLength = 1; // Độ dài của dãy con tăng dài nhất, ít nhất là 1
        for (int i = 0; i < nums.length; i++) {
            dp[i] = 1; // Khởi tạo độ dài tại vị trí i bằng 1
            for (int j = 0; j < i; j++) {
                if (nums[i] > nums[j] && dp[i] < dp[j] + 1) {
                    dp[i] = dp[j] + 1;
                }
            }
            maxLength = Math.max(maxLength, dp[i]);
        }
        return maxLength;
    }
    public static void main(String[] args) {
        int[] nums = {10, 22, 9, 33, 21, 50, 41, 60, 80};
        int longestLength = findLengthOfLIS(nums);
        System.out.println("Độ dài của dãy con tăng dài nhất là: " + longestLength);
    }
}

5 và

public class LongestIncreasingSubsequence {
    public static int findLengthOfLIS(int[] nums) {
        if (nums == null || nums.length == 0) {
            return 0;
        }
        int[] dp = new int[nums.length];
        int maxLength = 1; // Độ dài của dãy con tăng dài nhất, ít nhất là 1
        for (int i = 0; i < nums.length; i++) {
            dp[i] = 1; // Khởi tạo độ dài tại vị trí i bằng 1
            for (int j = 0; j < i; j++) {
                if (nums[i] > nums[j] && dp[i] < dp[j] + 1) {
                    dp[i] = dp[j] + 1;
                }
            }
            maxLength = Math.max(maxLength, dp[i]);
        }
        return maxLength;
    }
    public static void main(String[] args) {
        int[] nums = {10, 22, 9, 33, 21, 50, 41, 60, 80};
        int longestLength = findLengthOfLIS(nums);
        System.out.println("Độ dài của dãy con tăng dài nhất là: " + longestLength);
    }
}

6 là hai cấu trúc điều khiển quan trọng dùng để kiểm soát vòng lặp. Chúng cho phép bạn thoát khỏi vòng lặp hoặc bỏ qua một phần của nó tùy thuộc vào điều kiện. Dưới đây là giới thiệu về

public class LongestIncreasingSubsequence {
    public static int findLengthOfLIS(int[] nums) {
        if (nums == null || nums.length == 0) {
            return 0;
        }
        int[] dp = new int[nums.length];
        int maxLength = 1; // Độ dài của dãy con tăng dài nhất, ít nhất là 1
        for (int i = 0; i < nums.length; i++) {
            dp[i] = 1; // Khởi tạo độ dài tại vị trí i bằng 1
            for (int j = 0; j < i; j++) {
                if (nums[i] > nums[j] && dp[i] < dp[j] + 1) {
                    dp[i] = dp[j] + 1;
                }
            }
            maxLength = Math.max(maxLength, dp[i]);
        }
        return maxLength;
    }
    public static void main(String[] args) {
        int[] nums = {10, 22, 9, 33, 21, 50, 41, 60, 80};
        int longestLength = findLengthOfLIS(nums);
        System.out.println("Độ dài của dãy con tăng dài nhất là: " + longestLength);
    }
}

5 và

public class LongestIncreasingSubsequence {
    public static int findLengthOfLIS(int[] nums) {
        if (nums == null || nums.length == 0) {
            return 0;
        }
        int[] dp = new int[nums.length];
        int maxLength = 1; // Độ dài của dãy con tăng dài nhất, ít nhất là 1
        for (int i = 0; i < nums.length; i++) {
            dp[i] = 1; // Khởi tạo độ dài tại vị trí i bằng 1
            for (int j = 0; j < i; j++) {
                if (nums[i] > nums[j] && dp[i] < dp[j] + 1) {
                    dp[i] = dp[j] + 1;
                }
            }
            maxLength = Math.max(maxLength, dp[i]);
        }
        return maxLength;
    }
    public static void main(String[] args) {
        int[] nums = {10, 22, 9, 33, 21, 50, 41, 60, 80};
        int longestLength = findLengthOfLIS(nums);
        System.out.println("Độ dài của dãy con tăng dài nhất là: " + longestLength);
    }
}

6:

Break

Câu lệnh

public class LongestIncreasingSubsequence {
    public static int findLengthOfLIS(int[] nums) {
        if (nums == null || nums.length == 0) {
            return 0;
        }
        int[] dp = new int[nums.length];
        int maxLength = 1; // Độ dài của dãy con tăng dài nhất, ít nhất là 1
        for (int i = 0; i < nums.length; i++) {
            dp[i] = 1; // Khởi tạo độ dài tại vị trí i bằng 1
            for (int j = 0; j < i; j++) {
                if (nums[i] > nums[j] && dp[i] < dp[j] + 1) {
                    dp[i] = dp[j] + 1;
                }
            }
            maxLength = Math.max(maxLength, dp[i]);
        }
        return maxLength;
    }
    public static void main(String[] args) {
        int[] nums = {10, 22, 9, 33, 21, 50, 41, 60, 80};
        int longestLength = findLengthOfLIS(nums);
        System.out.println("Độ dài của dãy con tăng dài nhất là: " + longestLength);
    }
}

5 được sử dụng để thoát khỏi vòng lặp hoặc một khối code (block) lệnh. Khi câu lệnh

public class LongestIncreasingSubsequence {
    public static int findLengthOfLIS(int[] nums) {
        if (nums == null || nums.length == 0) {
            return 0;
        }
        int[] dp = new int[nums.length];
        int maxLength = 1; // Độ dài của dãy con tăng dài nhất, ít nhất là 1
        for (int i = 0; i < nums.length; i++) {
            dp[i] = 1; // Khởi tạo độ dài tại vị trí i bằng 1
            for (int j = 0; j < i; j++) {
                if (nums[i] > nums[j] && dp[i] < dp[j] + 1) {
                    dp[i] = dp[j] + 1;
                }
            }
            maxLength = Math.max(maxLength, dp[i]);
        }
        return maxLength;
    }
    public static void main(String[] args) {
        int[] nums = {10, 22, 9, 33, 21, 50, 41, 60, 80};
        int longestLength = findLengthOfLIS(nums);
        System.out.println("Độ dài của dãy con tăng dài nhất là: " + longestLength);
    }
}

5 được gọi, vòng lặp sẽ ngừng thực hiện và chương trình sẽ tiếp tục thực hiện các câu lệnh sau vòng lặp hoặc block hiện tại.

Ví dụ 1: Sử dụng break trong vòng lặp for

for (int i = 1; i <= 10; i++) {
    if (i == 5) {
        break; // Thoát khỏi vòng lặp khi i == 5
    }
    System.out.println(i);
}

Kết quả sẽ in ra các số từ 1 đến 4.

Ví dụ 2: Sử dụng break trong vòng lặp while

public class NestedForLoopExample {
    public static void main(String[] args) {
        for (int i = 1; i <= 3; i++) {
            for (int j = 1; j <= 3; j++) {
                System.out.println("i: " + i + ", j: " + j);
            }
        }
    }
}

0

Kết quả sẽ in ra các số từ 1 đến 4, tương tự như ví dụ trước.

Continue

Câu lệnh

public class LongestIncreasingSubsequence {
    public static int findLengthOfLIS(int[] nums) {
        if (nums == null || nums.length == 0) {
            return 0;
        }
        int[] dp = new int[nums.length];
        int maxLength = 1; // Độ dài của dãy con tăng dài nhất, ít nhất là 1
        for (int i = 0; i < nums.length; i++) {
            dp[i] = 1; // Khởi tạo độ dài tại vị trí i bằng 1
            for (int j = 0; j < i; j++) {
                if (nums[i] > nums[j] && dp[i] < dp[j] + 1) {
                    dp[i] = dp[j] + 1;
                }
            }
            maxLength = Math.max(maxLength, dp[i]);
        }
        return maxLength;
    }
    public static void main(String[] args) {
        int[] nums = {10, 22, 9, 33, 21, 50, 41, 60, 80};
        int longestLength = findLengthOfLIS(nums);
        System.out.println("Độ dài của dãy con tăng dài nhất là: " + longestLength);
    }
}

6 được sử dụng để bỏ qua phần còn lại của vòng lặp trong một lần lặp cụ thể. Khi câu lệnh

public class LongestIncreasingSubsequence {
    public static int findLengthOfLIS(int[] nums) {
        if (nums == null || nums.length == 0) {
            return 0;
        }
        int[] dp = new int[nums.length];
        int maxLength = 1; // Độ dài của dãy con tăng dài nhất, ít nhất là 1
        for (int i = 0; i < nums.length; i++) {
            dp[i] = 1; // Khởi tạo độ dài tại vị trí i bằng 1
            for (int j = 0; j < i; j++) {
                if (nums[i] > nums[j] && dp[i] < dp[j] + 1) {
                    dp[i] = dp[j] + 1;
                }
            }
            maxLength = Math.max(maxLength, dp[i]);
        }
        return maxLength;
    }
    public static void main(String[] args) {
        int[] nums = {10, 22, 9, 33, 21, 50, 41, 60, 80};
        int longestLength = findLengthOfLIS(nums);
        System.out.println("Độ dài của dãy con tăng dài nhất là: " + longestLength);
    }
}

6 được gọi, các câu lệnh còn lại trong vòng lặp sẽ bị bỏ qua và vòng lặp sẽ tiếp tục với lần lặp tiếp theo.

Ví dụ 1: Sử dụng continue trong vòng lặp for

public class NestedForLoopExample {
    public static void main(String[] args) {
        for (int i = 1; i <= 3; i++) {
            for (int j = 1; j <= 3; j++) {
                System.out.println("i: " + i + ", j: " + j);
            }
        }
    }
}

1

Kết quả sẽ in ra các số lẻ từ 1 đến 9.

Ví dụ 2: Sử dụng continue trong vòng lặp while

public class NestedForLoopExample {
    public static void main(String[] args) {
        for (int i = 1; i <= 3; i++) {
            for (int j = 1; j <= 3; j++) {
                System.out.println("i: " + i + ", j: " + j);
            }
        }
    }
}

2

Kết quả sẽ in ra các số lẻ từ 1 đến 9, tương tự như ví dụ trước.

Sử dụng Break và Continue trong Các Tình Huống Thực Tế

  • Break: Break thường được sử dụng để kết thúc một vòng lặp khi bạn đã tìm thấy một giá trị hoặc điều kiện cụ thể. Ví dụ, trong một vòng lặp để tìm kiếm một phần tử trong một mảng, bạn có thể sử dụng break khi tìm thấy phần tử này.
  • Continue: Continue thường được sử dụng khi bạn muốn bỏ qua một số lần lặp cụ thể và tiếp tục với các lần lặp khác. Ví dụ, trong một vòng lặp để xử lý các số lẻ và số chẵn riêng biệt, bạn có thể sử dụng continue để bỏ qua số chẵn và chỉ xử lý số lẻ.

Cả break và continue đều là công cụ quan trọng giúp kiểm soát vòng lặp và thực hiện các tác vụ lặp lại một cách hiệu quả trong Java.

Lời kết

Trong bài viết này, ta đã tìm hiểu về vòng lặp "for" lồng, vòng lặp do-while, và hai từ khoá quan trọng trong lập trình Java là "break" và "continue". Vòng lặp "for" lồng cho phép thực hiện các lặp lồng nhau, trong khi vòng lặp do-while đảm bảo rằng một khối code sẽ thực hiện ít nhất một lần. "Break" cho phép bạn thoát khỏi vòng lặp hoặc khối code, trong khi "continue" cho phép bỏ qua một phần của vòng lặp trong một lần lặp cụ thể.

Sự hiểu biết và sử dụng linh hoạt các cấu trúc lặp và các từ khoá điều khiển như "break" và "continue" là quan trọng trong việc xây dựng các ứng dụng Java hiệu quả. Chúng giúp bạn kiểm soát luồng của chương trình và thực hiện các tác vụ lặp lại theo cách mong muốn.

Hy vọng rằng sau bài viết này, bạn đã nắm rõ cách sử dụng các cấu trúc và từ khoá này một cách hiệu quả trong lập trình Java.