PDA

View Full Version : CTDL: tìm lỗi logic.



integer
04-10-2010, 12:17 AM
bài dưới đây là 1 lỗi thường gặp khi các bạn làm bt CTDL. các bạn xem tại sao không xóa được các số nhỏ hơn 10 ?. cùng thảo luận và rút kinh nghiệm.:001:

/*##### LT03C - VietHanIT ######*/
#include<stdio.h>
#define max 20
typedef struct{
int ds[max];
int ptcuoi;
}danhsach;

int kiemtra(danhsach D,int x)
{
for(int i=0;i<D.ptcuoi;)
{
if(D.ds[i]==x)
return i;
else
i++;
}
return -1;
}
//xoa 1 so
void xoa(danhsach &D,int x)
{
int i;
for(i=0;i<D.ptcuoi;i++)
if(D.ds[i]==x)
{
for(int j=i;j<=D.ptcuoi;j++)
D.ds[j]=D.ds[j+1];
}D.ptcuoi--;
}
//chen
void chen(danhsach &D,int so,int vt)
{
int i;
for(i=D.ptcuoi;i>=vt;i--)
{
D.ds[i+1]=D.ds[i];
}
D.ptcuoi++;
D.ds[vt]=so;

}
//tim min
int min(danhsach D)
{
int min=D.ds[0];
for(int i=0;i<D.ptcuoi;i++)
if(D.ds[i]<min)
min=D.ds[i];
return min;
}
int daytang(danhsach D)
{
for(int i=0;i<D.ptcuoi;)
if(D.ds[i]>D.ds[i+1])
return 1;
else
i++;
return 0;
}

void inds(danhsach D)
{
for(int i=0;i<D.ptcuoi;i++)
printf("%d ",D.ds[i]);
printf("\n");
}
main()
{
int i,int_n,int_x;
danhsach D;
//tao ds
D.ptcuoi=0;
//nhap ds
printf("\nNhap so phan tu ds: ");
scanf("%d",&int_n);
for(i=0;i<int_n;i++)
{
printf("\nNhap %d: ",i+1);
scanf("%d",&D.ds[i]);
D.ptcuoi++;
}
inds(D);
//kiem tra tang giam cua day
if(daytang(D)==1)
printf("\nDay khong tang!");
else
printf("\nDay tang!");
//min
printf("\nPhan tu nho nhat: %d",min(D));

//nhap so nguyen x, kiem tra co thuoc day hay khong
printf("\nNhap X: ");
scanf("%d",&int_x);
if(kiemtra(D,int_x)==-1)
printf("\nX Khong thuoc day!");
else
printf("\nvi tri cua x: %d ",kiemtra(D,int_x)+1);


//xoa
int int_xoa,int_vt;
printf("\nNhap so can xoa: ");
scanf("%d",&int_xoa);
if(kiemtra(D,int_xoa)==-1)
printf("\n\aVi tri khong hop le!\n");
else
xoa(D,int_xoa);
inds(D);

//chen so vao vi tri
int int_chen,int_vtchen;

printf("\nNhap so can chen: ");
scanf("%d",&int_chen);
printf("\nVi tri can chen: ");
scanf("%d",&int_vtchen);
int_vtchen-=1;
chen(D,int_chen,int_vtchen);
inds(D);
//xoa so nho hon 10
printf("\nXoa cac so nho hon 10\n");
for(i=0;i<D.ptcuoi;i++)
{
for(int j=i;j<=D.ptcuoi;j++)
if(D.ds[j]<10)
xoa(D,D.ds[j]);
}
inds(D);

}

hoekaka
04-10-2010, 11:12 AM
mắc lỗi này có lẽ là nhiều bạn dùng hàm for .. mà biến i của hàm for khi xóa sẽ khác vs vị trí các phần tử (khi xóa thì vị trí các pt trong ds sẽ bị thay đổi) còn biến i trong for thì ko ..

mình hiểu thế .. viết ra chắc hơi khó hiểu :D

integer
04-10-2010, 01:02 PM
mình cũng nghĩ thế, hàm xóa dùng để xóa giá trị. còn khi xóa các số nhỏ hơn 10 ta lại truyền cho nó vị trí.
bạn để ý cái này không:

//xoa
int int_xoa,int_vt;
printf("\nNhap so can xoa: ");
scanf("%d",&int_xoa);
if(kiemtra(D,int_xoa)==-1)
printf("\n\aVi tri khong hop le!\n");
else
xoa(D,int_xoa);
inds(D);

LieuKyThien
09-10-2010, 01:19 PM
Hơ! nếu thảo luận về cách xóa những phần tử <= x thì nên post đoạn mã xử lý thôi chứ làm nguyên sơ ri thế này đọc mỏi mắt quá. Góp ý nè:
for(i=0;i<n;)
{
if(a[i]<x)
xóa;
else
i++;
}
Nếu xóa thì không tăng i còn không xóa thì tăng lên để duyệt phần tử tiếp theo

TruTra
09-10-2010, 04:45 PM
Đơn giản là thế này
for(i=0;i<D.ptcuoi;i++)
if(D.ds[i]==x)
{
for(int j=i;j<=D.ptcuoi;j++)
D.ds[j]=D.ds[j+1];
}D.ptcuoi--;
Ở đây 1 lần gọi hàm là một lần
D.ptcuoi--;
Vì thế chỉ xóa được một lần thoai.
Xem lai dễ...
Còn việc đặt thêm vòng lặp j=i là hoàn toàn phung phí.
Cái này có thể rút gọn lại cho i và i+1

integer
09-10-2010, 07:28 PM
Đơn giản là thế này
for(i=0;i<D.ptcuoi;i++)
if(D.ds[i]==x)
{
for(int j=i;j<=D.ptcuoi;j++)
D.ds[j]=D.ds[j+1];
}D.ptcuoi--;
Ở đây 1 lần gọi hàm là một lần
D.ptcuoi--;
Vì thế chỉ xóa được một lần thoai.
Xem lai dễ...
Còn việc đặt thêm vòng lặp j=i là hoàn toàn phung phí.
Cái này có thể rút gọn lại cho i và i+1
uhm, chỗ này thừa 1 chút, ban đầu lấy ra từ thuật toán sắp xếp, mình quên đổi lại.
ai biết disasm ra như thế nào không.