Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Lập Trình C

Xóa nguyên âm (vowels) khỏi chuỗi trong C

Mô tả bài toán

Nhập một chuỗi ký tự, xóa tất cả các nguyên âm (a, e, i, o, u - cả chữ hoa và thường), in chuỗi kết quả.

Thuật toán

  1. Đọc chuỗi từ bàn phím (dùng fgets để đọc cả khoảng trắng)
  2. Duyệt từng ký tự của chuỗi
  3. Nếu ký tự là nguyên âm → dịch chuyển các ký tự sau lên trước 1 vị trí
  4. Giảm độ dài chuỗi đi 1
  5. Lặp lại cho đến hết chuỗi

Chương trình C

#include <stdio.h>
#include <string.h>

int main() {
    char str[100];
    int len, i, j;
    
    printf("Nhap chuoi: ");
    fgets(str, sizeof(str), stdin);
    
    // Xóa ký tự newline nếu có
    len = strlen(str);
    if (len > 0 && str[len - 1] == '\n') {
        str[len - 1] = '\0';
        len--;
    }
    
    // Xóa nguyên âm
    for (i = 0; i < len; i++) {
        char c = str[i];
        
        // Kiểm tra nguyên âm (cả hoa và thường)
        if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u' ||
            c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U') {
            
            // Dịch chuyển các ký tự sau lên trước
            for (j = i; j < len; j++) {
                str[j] = str[j + 1];
            }
            len--;   // Giảm độ dài
            i--;     // Kiểm tra lại vị trí hiện tại (vì đã dịch chuyển)
        }
    }
    
    printf("Chuoi sau khi xoa nguyen am: %s\n", str);
    
    return 0;
}

Kết quả

Nhap chuoi: TutorialsPoint
Chuoi sau khi xoa nguyen am: TtrlsPnt

Phân tích thuật toán

Bước i Ký tự Là nguyên âm? Hành động
10TKhôngGiữ lại
21uCóXóa, dịch chuyển, len--, i--
31tKhôngGiữ lại
42oCóXóa...
...............

Cách tiếp cận tốt hơn: Tạo chuỗi mới

Thay vì dịch chuyển (O(n²)), tạo chuỗi mới chỉ chứa phụ âm (O(n)):

#include <stdio.h>
#include <string.h>
#include <ctype.h>

int laNguyenAm(char c) {
    c = tolower(c);
    return (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u');
}

int main() {
    char str[100], ketQua[100];
    int i, j = 0;
    
    printf("Nhap chuoi: ");
    fgets(str, sizeof(str), stdin);
    str[strcspn(str, "\n")] = 0;  // Xóa newline
    
    for (i = 0; str[i] != '\0'; i++) {
        if (!laNguyenAm(str[i])) {
            ketQua[j++] = str[i];
        }
    }
    ketQua[j] = '\0';
    
    printf("Ket qua: %s\n", ketQua);
    return 0;
}

So sánh 2 cách

Tiêu chí Xóa tại chỗ (In-place) Tạo chuỗi mới
Độ phức tạp thời gianO(n²) - dịch chuyển nhiều lầnO(n) - duyệt 1 lần
Bộ nhớO(1) - không thêm bộ nhớO(n) - cần mảng phụ
CodePhức tạp hơn (i--, len--)Đơn giản, dễ đọc
Phù hợpNhúng, bộ nhớ hạn chếỨng dụng chung, khuyến nghị

Mở rộng

  • Xóa ký tự số, ký tự đặc biệt
  • Chỉ giữ lại chữ cái (isalpha)
  • Chuẩn hóa chuỗi: viết hoa chữ cái đầu, xóa khoảng trắng thừa
  • Đếm số nguyên âm/phụ âm

Bài toán này rèn luyện thao tác mảng ký tự, con trỏ, và tư duy tối ưu thuật toán.