Code xoá kí tự trong xâu bị sai kết quả

chào mn code em ra sai kq ạ mn giúp em với ạ
Đề bài :

Bài 2: Xâu đúng (5 điểm)
Viết chương trình nhập từ bàn phím một xâu kí tự, trong đó, nếu tính từ trái sang phải thì kí tự # là dấu hiệu xóa đi một kí tự đứng ngay trước nó (nếu có). Sau đó in ra màn hình xâu đã sửa theo đúng qui định.
Ví dụ:
‘Ta#oi di thi hoc sinua#h###nh gioi tin hoj#c THCS’ có nghĩa là ‘Toi di thi hoc sinh gioi tin hoc THCS’
Dữ liệu: Nhập từ bàn phím một xâu kí tự cần sửa.
Kết quả: In ra màn hình xâu đã sửa.

CODE :

#include <bits/stdc++.h>

using namespace std;
void xoa(char str[], int &n, int vitri)
{
    for (int i=vitri;i<n-1;i++)
          str[i] = str[i+1];
      n--;
}
int main()
{
   ifstream fi;
   fi.open("SUAXAU.INP");
   char str[100];
   fi.getline(str,100);
   int n = strlen(str);
   for (int i=0;i<n;i++) {
    if (str[i]=='#') {
        xoa(str,n,i);
        xoa(str,n,(i-1));
    }
   }
   ofstream fo ("SUAXAU.OUT");
   for (int i=0;i<n;i++) fo <<str[i];
   fo.close();
   fi.close();
    return 0;
}

Xóa cả dấu # và kí tự trước nó. Nghĩa là XÓA 02 KÍ TỰ!

2 Likes

rồi mà anh !
input :‘Ta#oi thi hoc sinua#h###nh gioi tin hoj#c’
output:‘Toi thi hoc sinuh#nh gioi tin hoc’
đáng lẽ phải là : Toi thi hoc sinh gioi tin hoc
sai ở chữ “sinh” ấy

@SITUVN.gcd ở output em bị sai chữ “sinh” ấy thôi ạ

Code này còn sai ở chỗ không thay đổi n (thật ra cách này có hai chỗ không hay nhưng từ từ ta bàn sau).

:D
var f = s => s.replace(/.#/g, "");
3 Likes

Theo mình thì nên xóa 2 kí tự một lần và sau một lần xóa thì giảm i đi 1 đơn vị, giảm n đi 2 đơn vị

2 Likes

anh giải thích cho em dòng này đc k ạ :frowning:

Đó là Javascript, dùng Regex (biểu thức chính quy) để xóa các kí tự cần xóa.

2 Likes

Mình sửa như vầy:

#include <bits/stdc++.h>

using namespace std;

void moveEnd(char str[], int n, int vitri) // Di chuyen ky tu duoc chon ve cuoi xau.
{
    for (int i = vitri; i < (n - 1); i++)
    {
       str[i] = str[i + 1];
    }
}
    

int main()
{
    ifstream fi;
     int n = strlen(str);
     int i = 0;
     char str[100];

     fi.open("SUAXAU.INP");
     fi.getline(str, 100);

     while (i < n) {
         if (str[i] == '#')
         {
             moveEnd(str, n, i);
             if (str[i - 1]) // Kiem tra neu co ky tu ton tai thi xoa, khong thi chi can xoa ky tu '#'.
             {
                 moveEnd(str, n, (i - 1));
                 n--; // Giam so luong xau ban dau di 1 neu ky tu do ton tai.
             }
             n--; // Giam so luong ky tu cua xau xuong.
             i--; // Neu gap ky tu '#' thi khong duoc chuyen vi tri dang xet, do tong do dai chuoi da bi giam (lien quan toi else o duoi).
         }
         else // Neu khong gap ky tu '#' thi moi duoc chuyen qua ky tu tiep theo.
         {
             i++;
         }
     }

     ofstream fo ("SUAXAU.OUT");

     for (int i = 0; i < n; i++)
    {
         fo << str[i];
    }

     fo.close();
     fi.close();
     return 0;
 }

Dựa vào code xoá 1 kí tự bằng 1 for :slight_smile:

if(*s == '\0') return;
char* t = ++s;
while(*s)  {
   if(*s == '#') --t, ++s; //xoá kí tự đã ghi liền trước
   else *t++ = *s++;
}
*t = '\0';

Có thể viết lại để tránh post-increment :slight_smile:

3 Likes

có chữ “nếu có” mà, nghĩa là # vẫn có thể đứng ở đầu chuỗi :V Ví dụ “####” phải trả về chuỗi rỗng "". Dấu # này hoạt động giống phím backspace.

3 Likes
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?