Bài tập C++ Bỏ khoảng trống thừa trong chuỗi chỉ sử dụng các vòng lặp? [Archive] – Cộng đồng C Việt

View Full Version : Bài tập C++ Bỏ khoảng trống thừa trong chuỗi chỉ sử dụng các vòng lặp?

moitaplaptrinh

Thực hiện chuẩn hóa xâu s theo yêu cầu sau:các từ trong xâu chỉ cách nhau một ký tự trắng.
ai có thể giúp mình làm bài tập đó chỉ bằng các vòng lặp như for, while, do while được không vì mình mới chỉ được học đến vậy thui à.
các bạn lưu là cho dù mình nhập bao nhiêu khoảng trống đi nữa thì khi in ra những từ đó chỉ cách nhau một khoảng trống.

mp121209

Dùng for, while là đủ rồi đó bạn!
1. Xóa hết dấu cách ở đầu chuỗi, cuối chuỗi.

// Xóa ở đầu
for (;str[0] == ‘ ‘;)
for(int i = 0; i < strlen(str); ++i)
str[i] = str[i + 1];
// Xóa ở cuối
size_t size = strlen(str);
while(str[size–] == ‘ ‘)
str[size] = str[size + 1];
2. Xóa ở giữa nếu có hai dấu cách liên tiếp

size_t size = strlen(str);
for (size_t i = 0; i < size; ++i)
if (; str[i] == str[i + 1] && str[i + 1] == ‘ ‘)
for(int j = i + 1; j < size; ++j)
{
str[j] = str[j + 1];
— size;
}

moitaplaptrinh

cám ơn bạn nha bài cảu bạn ngắn gọn mà dễ hiểu

kitti

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

int main ()
{
clrscr();
char pChuoi[100];
char* pChuoiXuly;
int i;
int n;
int k;
char s = 0;
printf(“\n Nhap mot Chuoi bat ky: “);
gets(pChuoi);
n = strlen(pChuoi);
pChuoiXuly = (char*)malloc(n);
pChuoiXuly[0] = 0;

k = 0;
for( i = 0; i < n; i++)
{
if(pChuoi[i] != ‘ ‘ && pChuoiXuly[0] == 0)
{
pChuoiXuly[k] = pChuoi[i];
k++;
} else if(s != ‘ ‘ || pChuoi[i] != ‘ ‘)
{
pChuoiXuly[k] = pChuoi[i];
k++;
}
s = pChuoi[i];
}
if(s == ‘ ‘) pChuoiXuly[k – 1] = ‘\0’;

pChuoiXuly[k] = ‘\0’;
printf(“\n pChuoi toi uu: %s”, pChuoiXuly);
free(pChuoiXuly);
getch();
return 0;
}

Cái này chắc là đúng yêu cầu.

huugiang954

G chia sẻ hàm Trim, TrimEx, TrimEx2.

Đoạn Trim_Space: Không xóa khoảng trắng trước sau.

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

void Trim_Space(char pcData[]){ // Chưa Loại bỏ khoảng trắng ở đầu và cuối
int i;
int n = strlen(pcData);
for(i = 0; i < n – 1; i++){
if(pcData[i] == ‘ ‘ && pcData[i + 1] == ‘ ‘){
for(int j = i + 1; j < n – 1; j++){ // Đẩy khoảng trắng ra phía Sau
char cTemp = pcData[j];
pcData[j] = pcData[j + 1];
pcData[j + 1] = cTemp;
}
i–; // Lùi lại 1 bước
n–; // Giảm n loại bỏ khoảng trắng ở phía Sau
}
}
pcData[n] = ‘\0’; // Kết thúc Chuỗi
}

int main(){
char sv[100];
printf(“Nhap Chuoi: “);
gets(sv);
printf(“Chuoi vua Nhap: %s\n”, sv);
Trim_Space(sv);
printf(“Chuoi sau khi dung ham Trim(): %s”, sv);
}

Đoạn TrimEx: Xóa Khoảng Cách lặp, trước đầu, sau.

void TrimEx(char pcData[]){
int i;
int n = strlen(pcData);
for(i = 0; i < n; i++){ // Chạy đến giá trị ‘\0’ để kiểm tra phần tử cuối cùng
if(pcData[i] == ‘ ‘){
int nBegin = i;

if(pcData[i + 1] == ‘ ‘){
nBegin = i + 1;
}

if(pcData[i + 1] == ‘ ‘ || i == 0 || i == n – 2){
for(int j = nBegin; j < n – 1; j++){
char cTemp = pcData[j];
pcData[j] = pcData[j + 1];
pcData[j + 1] = cTemp;
}
i–;
n–;
}
}
}
pcData[n] = ‘\0’;
}

Đoạn này:

int nBegin = i;

if(pcData[i + 1] == ‘ ‘){
nBegin = i + 1;
}

Có thể thay thế bằng:

int nBegin_Swap = (pcData[i + 1] == ‘ ‘)? i + 1 : i;

Hàm TrimEx2: Tương tự như TrimEx(), nhưng chỉ bỏ qua vòng lặp cuối cùng khi ký tự cuối là Khoảng Cách và chỉ chạy i < n – 1.

void TrimEx2(char pcData[]){
int i;
int n = strlen(pcData);
for(i = 0; i < n – 1; i++){ // Chạy đến giá trị n – 1
if(pcData[i] == ‘ ‘){
int nBegin_Swap = (pcData[i + 1] == ‘ ‘)? i + 1 : i;

if(pcData[i + 1] == ‘ ‘ || i == 0){
for(int j = nBegin_Swap; j < n – 1; j++){
char cTemp = pcData[j];
pcData[j] = pcData[j + 1];
pcData[j + 1] = cTemp;
}
i–;
n–;
}
}
}

if(pcData[n – 1] == ‘ ‘){
n–;
}

pcData[n] = ‘\0’;
}

thansautk

Dùng for, while là đủ rồi đó bạn!

2. Xóa ở giữa nếu có hai dấu cách liên tiếp

size_t size = strlen(str);
for (size_t i = 0; i < size; ++i)
if (; str[i] == str[i + 1] && str[i + 1] == ‘ ‘)
for(int j = i + 1; j < size; ++j)
{
str[j] = str[j + 1];
— size;
}

Bạn có chắc code này của bạn đúng không? Trường hợp có nhiều dấu cách liên tiếp mình nghĩ giải thuật này sẽ bị sai

huugiang954

Thêm hàm TrimEx() rút gọn: Xóa Khoảng Cách lặp, đầu, sau.

void TrimEx(char pcData[]){
int n = strlen(pcData);
int k = 0;
int i;
for(i = 0; i < n; i++){
if(pcData[i] == ‘ ‘){
if(pcData[i + 1] == ‘ ‘ || k == 0){
// Kỹ thì pcData[i] = ‘\0’ // Hủy ký tự tại i;
continue;
}
}
pcData[k++] = pcData[i];
}

if(pcData[k – 1] == ‘ ‘){
k–;
}
pcData[k] = ‘\0’; // Kết thúc chuỗi!
}

Thêm Hàm Trim() đúng nghĩa (chỉ xóa khoảng trắng trước sau):

int Length(const char *pcData){
char *pcTemp = (char *)pcData;
int nCount = 0;
while(*(pcTemp)++){
nCount++;
}
return nCount;
}

int IsWhiteSpace(char cData){
switch (cData){
case 0x0009: // HT (Horizontal Tabulation)
case 0x000A: // LF (Line Feed)
case 0x000B: // VT (Vertical Tabulation)
case 0x000C: // FF (Form Feed)
case 0x000D: // CR (Carriage Return)
case 0x0020: // Space
// Unicode
case 0x0085: // NEL (control character next line)
case 0x00A0: // No-break Space
case 0x1680: //
case 0x180E: //
case 0x2000: // (different sorts of spaces)
case 0x2001: //
case 0x2002: //
case 0x2003: //
case 0x2004: //
case 0x2005: //
case 0x2006: //
case 0x2007: //
case 0x2008: //
case 0x2009: //
case 0x200A: //
case 0x2028: // LS (Line Separator)
case 0x2029: // PS (Paragraph Separator)
case 0x202F: // NNBSP (Narrow No-Break Space)
case 0x205F: // MMSP (Medium Mathematical Space)
case 0x3000: // Ideographic Space
return 1;
default:
return 0;
}
}

char *Trim(const char *pcData){
int nData = Length(pcData);
char *pcTemp = (char *) calloc(nData, sizeof(char));
int k = 0;
for(int i = 0; i < nData; i++){ // Remove ký tự WhiteSpace ở Đầu Câu
if(k == 0 && IsWhiteSpace(pcData[i]) == 1){
continue;
}
pcTemp[k++] = pcData[i];
}

while(k > 0){ // Remove ký tự WhiteSpace ở Cuối Câu
if(IsWhiteSpace(pcTemp[k – 1]) == 1){
pcTemp[k – 1] = 0x00;
}else{
break;
}
k–;
}

char *pcRet = (char *) calloc((k + 1), sizeof(char));
memcpy(pcRet, pcTemp, k * sizeof(char));
free(pcTemp);
return pcRet;
}

Giải đáp:

Bạn có chắc code này của bạn đúng không? Trường hợp có nhiều dấu cách liên tiếp mình nghĩ giải thuật này sẽ bị sai

2. Xóa ở giữa nếu có hai dấu cách liên tiếp

size_t size = strlen(str);
for (size_t i = 0; i < size; ++i)
if (; str[i] == str[i + 1] && str[i + 1] == ‘ ‘)
for(int j = i + 1; j < size; ++j)
{
str[j] = str[j + 1];
— size;
}

G sửa lại vài thứ trong code của mp121209:

size_t size = strlen(str);
for (size_t i = 0; i < size; ++i)
if (str[i] == str[i + 1] && str[i + 1] == ‘ ‘)
{
for(int j = i + 1; j < size; ++j)
str[j] = str[j + 1];
–size;
–i;
}

voldemost20

[QUOTE=mp121209;246032]Dùng for, while là đủ rồi đó bạn!
1. Xóa hết dấu cách ở đầu chuỗi, cuối chuỗi.

// Xóa ở đầu
for (;str[0] == ‘ ‘;)
for(int i = 0; i < strlen(str); ++i)
str[i] = str[i + 1];
// Xóa ở cuối
size_t size = strlen(str);
while(str[size–] == ‘ ‘)
str[size] = str[size + 1];
bạn ơi, bạn có thể giải thích thuật toán xóa ở cuối của bạn không 😀
mình chưa hiểu rõ lắm, mới hiểu được xóa ở đầu thôi, bạn nói bằng lời được không

ANHMATTROI

bạn cho biến i chạy từ cuối chạy về đầu nếu tại i là dấu cách thì gán bằng kí tự kết thúc sâu còn nếu không phải thì dừng

cvht

Về cách làm, bạn chỉ cần lưu ý là khi gặp dấu trắng đầu tiên thì sẽ tiếp tục đọc xâu s để bỏ qua những dấu trắng ngay sau dấu trắng đầu tiên. Cách làm này sẽ tránh được kiểm tra 2 lần xem một kí tự có là dấu cách hay không như trong một số bài trả lời trước. Đây là đoạn code theo cách này:

void squeeze(char *s)
{
char *p = s;
do {
if (*p == ‘ ‘) {
*s++ = *p++;
while (*p == ‘ ‘) ++p;
}
} while ((*s++ = *p++) != ‘\0’);
}

Con trỏ p được dùng để duyệt chuỗi và để bỏ qua các dấu cách liên tiếp nhau. Con trỏ s trỏ vào ô nhớ tiếp theo để copy kí tự trỏ bởi p.

Thực hiện chuẩn hóa xâu s theo yêu cầu sau:các từ trong xâu chỉ cách nhau một ký tự trắng.
ai có thể giúp mình làm bài tập đó chỉ bằng các vòng lặp như for, while, do while được không vì mình mới chỉ được học đến vậy thui à.
các bạn lưu là cho dù mình nhập bao nhiêu khoảng trống đi nữa thì khi in ra những từ đó chỉ cách nhau một khoảng trống.

nguyenducnam90

#include<stdio.h>
#include<conio.h>
#include<string.h>
char s[100];
int i,j,n;
int chuan_hoa(char s[]){
n=strlen(s);
for(i=0;i<n;i++)
{
if(s[0]==’ ‘&&s[i]==’ ‘&&s[i+1]==’ ‘)
{
for(j=i;j<n;j++)
s[j]=s[j+1];
n–;
i–;
}
}
return n;
}
int main(){
printf(“\nNhap xau:”);
gets(s);
n=chuan_hoa(s);
printf(“Chuoi xau khi chuan hoa:”);
printf(“%s\n”, s);
}