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);
}