Sắp xếp và xử lý chuỗi ký tự trong C

Bài 1: Sắp xếp ký tự tại vị trí lẻ theo thứ tự giảm dần

Yêu cầu: Viết hàm void sapXepViTriLe(char mang[]) để sắp xếp các ký tự ở chỉ số lẻ (1, 3, 5...) theo giá trị ASCII giảm dần.

Ví dụ: Chuỗi "abcdefgh" → "ahcfedgb"

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

void sapXepViTriLe(char mang[])
{
    int doDai, m, n;
    char tam;
    doDai = strlen(mang);
    for (m = 1; m < doDai - 2; m += 2)
        for (n = m + 2; n < doDai; n += 2)
            if (mang[m] < mang[n])
            {
                tam = mang[m];
                mang[m] = mang[n];
                mang[n] = tam;
            }
}

int main()
{
    char mang[81];
    printf("Nhap chuoi: ");
    gets(mang);
    printf("Chuoi goc: ");
    puts(mang);
    sapXepViTriLe(mang);
    printf("Chuoi sau khi xu ly: ");
    puts(mang);
    return 0;
}

Bài 2: Sắp xếp hai nửa chuỗi theo chiều ngược nhau

Yêu cầu: Chia chuỗi làm đôi, nửa trái sắp xếp giảm dần, nửa phải sắp xếp tăng dần. Nếu độ dài lẻ, ký tự giữa giữ nguyên vị trí.

Ví dụ: "abcdhgfe" → "dcbaefgh"; "123498765" → "432195678"

void sapXepHaiNua(char mang[])
{
    int doDai, m, n, giua;
    char tam;
    doDai = strlen(mang);
    giua = doDai / 2;
    
    /* Sắp xếp nửa trái giảm dần */
    for (m = 0; m < giua - 1; m++)
        for (n = m + 1; n < giua; n++)
            if (mang[m] < mang[n])
            {
                tam = mang[m];
                mang[m] = mang[n];
                mang[n] = tam;
            }
    
    /* Điều chỉnh vị trí bắt đầu nửa phải nếu độ dài lẻ */
    if (doDai % 2) giua++;
    
    /* Sắp xếp nửa phải tăng dần */
    for (m = giua; m < doDai - 1; m++)
        for (n = m + 1; n < doDai; n++)
            if (mang[m] > mang[n])
            {
                tam = mang[m];
                mang[m] = mang[n];
                mang[n] = tam;
            }
}

Bài 3: Sắp xếp nửa trái và hoán đổi hai nửa

Yêu cầu: Sắp xếp nửa trái giảm dần, sau đó hoán đổi vị trí hai nửa. Ký tự giữa giữ nguyên nếu độ dài lẻ.

Ví dụ: "abcdhgfe" → "hgfedcba"; "123498765" → "876594321"

void sapXepVaHoanDoi(char mang[])
{
    int doDai, m, n, giua;
    char tam;
    doDai = strlen(mang);
    giua = doDai / 2;
    
    /* Sắp xếp nửa trái giảm dần */
    for (m = 0; m < giua - 1; m++)
        for (n = m + 1; n < giua; n++)
            if (mang[m] < mang[n])
            {
                tam = mang[m];
                mang[m] = mang[n];
                mang[n] = tam;
            }
    
    /* Hoán đổi hai nửa */
    for (m = giua - 1, n = doDai - 1; m >= 0; m--, n--)
    {
        tam = mang[m];
        mang[m] = mang[n];
        mang[n] = tam;
    }
}

Bài 4: Đếm số lần xuất hiện của chuỗi con 2 ký tự

Yêu cầu: Viết hàm int demChuoiCon(char *nguon, char *mau) đếm số lần chuỗi con 2 ký tự xuất hiện trong chuỗi nguồn.

Ví dụ: "asd asasdfg asd as zx67 asd mklo", mẫu "as" → kết quả 6

Cách 1: Duyệt từng vị trí

int demChuoiCon(char *nguon, char *mau)
{
    int ketQua = 0;
    char *p, *q;
    while (*nguon)
    {
        p = nguon;
        q = mau;
        while (*q)
            if (*q == *p) { q++; p++; }
            else break;
        if (*q == '\0') ketQua++;
        nguon++;
    }
    return ketQua;
}

Cách 2: So sánh trực tiếp từng cặp

int demChuoiCon(char *nguon, char *mau)
{
    int i, dem = 0;
    for (i = 0; nguon[i] != '\0'; i++)
        if (nguon[i] == *mau && nguon[i+1] == *(mau+1))
            dem++;
    return dem;
}

Bài 5: Đảo ngược thứ tự các từ trong chuỗi

Yêu cầu: Tách chuỗi thành các từ (phân cách bởi dấu cách hoặc dấu câu), đảo ngược thứ tự các từ, thay dấu câu bằng dấu cách.

Ví dụ: "I am a student" → "student a am I"

Cách 1: Duyệt ngược và xây dựng chuỗi mới

void daoNguocTu(char mang[])
{
    int doDai, i, j, k, viTri;
    char ketQua[81];
    doDai = strlen(mang);
    viTri = k = 0;
    
    for (i = doDai - 1; i >= 0; i--)
    {
        if ((mang[i] >= 'A' && mang[i] <= 'Z') || 
            (mang[i] >= 'a' && mang[i] <= 'z'))
            k++;
        else
        {
            for (j = 1; j <= k; j++)
                ketQua[viTri++] = mang[i + j];
            k = 0;
        }
        if (!((mang[i] >= 'A' && mang[i] <= 'Z') || 
              (mang[i] >= 'a' && mang[i] <= 'z')))
            ketQua[viTri++] = ' ';
    }
    
    for (j = 1; j <= k; j++)
        ketQua[viTri++] = mang[i + j];
    ketQua[viTri] = '\0';
    strcpy(mang, ketQua);
}

Cách 2: Sử dụng hàm chuẩn

void daoNguocTu(char mang[])
{
    int i, doDai;
    char ketQua[81] = {0};
    doDai = strlen(mang);
    
    for (i = doDai - 1; i >= 0; i--)
        if (!((mang[i] >= 'A' && mang[i] <= 'Z') || 
              (mang[i] >= 'a' && mang[i] <= 'z')))
        {
            strcat(ketQua, mang + i + 1);
            strcat(ketQua, " ");
            mang[i] = '\0';
        }
    strcat(ketQua, mang);
    strcpy(mang, ketQua);
}

Thẻ: C string manipulation Sorting Algorithms array processing Pointer Arithmetic

Đăng vào ngày 11 tháng 8 lúc 09:21